Framework that enables syncing between iCloud (CloudKit) and Core Data
Nowdays repository is not actively maintained, so I put that repo in an archived state because I can’t provide high-quality support and actual updates for that project. Maybe a little later I could take control of that and push a new version of CloudCore.
I recommend looking at Deeje’s pull request, he has implemented a lot of fixes and new features, but it’s not my code so I couldn’t guarantee anything.
CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift. It maybe used are CloudKit caching.
userDeletedZone
, zoneNotFound
, changeTokenExpired
, isMore
.CloudCore is built using “black box” architecture, so it works invisibly for your application, you just need to add several lines to AppDelegate
to enable it. Synchronization and error resolving is managed automatically.
CloudCore.enable
) it fetches changed data from CloudKit and subscribes to CloudKit push notifications about new changes.CloudCore.fetchAndSave
is called manually or by push notification, CloudCore fetches and saves changed data to Core Data.CloudCore is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'CloudCore', '~> 2.0'
Current version of framework hasn’t been deeply tested and may contain errors. If you can test framework, I will be very glad. If you found an error, please post an issue.
All public methods are documented using XCode Markup and available inside XCode.
HTML-generated version of that documentation is available here.
Enable CloudKit capability for you application:
Add 2 service attributes to each entity in CoreData model you want to sync:
recordData
attribute with Binary
typerecordID
attribute with String
typefunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Register for push notifications about changes
application.registerForRemoteNotifications()
// Enable CloudCore syncing
CloudCore.enable(persistentContainer: persistentContainer)
return true
}
// Notification from CloudKit about changes in remote database
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Check if it CloudKit's and CloudCore notification
if CloudCore.isCloudCoreNotification(withUserInfo: userInfo) {
// Fetch changed data from iCloud
CloudCore.fetchAndSave(using: userInfo, to: persistentContainer, error: nil, completion: { (fetchResult) in
completionHandler(fetchResult.uiBackgroundFetchResult)
})
}
}
func applicationWillTerminate(_ application: UIApplication) {
// Save tokens on exit used to differential sync
CloudCore.tokens.saveToUserDefaults()
}
CloudCore stores service CloudKit information in managed objects, you need to add that attributes to your Core Data model. If required attributes are not found in entity that entity won’t be synced.
Required attributes for each synced entity:
Binary
typeString
typeYou may specify attributes’ names in 2 ways (you may combine that ways in different entities).
First off CloudCore try to search attributes by looking up User Info at your model, you may specify User Info key CloudCoreType
for attribute to mark one as service one. Values are:
recordData
.recordID
.The most simple way is to name attributes with default names because you don’t need to specify any User Info.
myid
with User Info: CloudCoreType: recordID
)Indexed
, that can speed up updates in big databases.CKRecord
with system fields only (like timestamps, tokens), so don’t worry about size, no real data will be stored here.You can find example application at Example directory.
How to run it:
How to use it:
fetchAndSave
to fetch data from Cloud. That is useful button for simulators because Simulator unable to receive push notificationsCloudKit objects can’t be mocked up, that’s why I create 2 different types of tests:
Tests/Unit
here I placed tests that can be performed without CloudKit connection. That tests are executed when you submit a Pull Request.
Tests/CloudKit
here located “manual” tests, they are most important tests that can be run only in configured environment because they work with CloudKit and your Apple ID.
Nothing will be wrong with your account, tests use only private CKDatabase
for application.
Please run these tests before opening pull requests.
To run them you need to:
TestableApp
bundle id.TestableApp
target.CloudKitTests
, they are attached to TestableApp
, so CloudKit connection will work.CloudCore.disable
methodlimitExceeded
error (split saves by relationships).Open for hire / relocation.
Vasily Ulianov, va…@me.com