0

TLDR

How can I use cloudkit with core data in iOS versions previous to iOS 13?


I’m building an app that will work on iOS 12+.
I use core data and I also want to be able to upload the data in iCloud. I set up the persistent container using NSPersistentCloudKitContainer when available, but I still have some doubts. I currently manage the storage like this:

 //MARK: PersistentContainer
    lazy var persistentContainer: NSPersistentContainer = {
        let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: CoreHelp.appGroup)!
        let storeURL = containerURL.appendingPathComponent(CoreHelp.sql)
        let description = NSPersistentStoreDescription(url: storeURL)
        
        if #available(iOS 13.0, *) { //ios 13+
            let container = NSPersistentCloudKitContainer(name: CoreHelp.appName)
            container.loadPersistentStores(completionHandler: {
                (storeDescription, error) in
                if let error = error as NSError? {
                    fatalError("Unresolved error \(error), \(error.userInfo)")
                }
            })
            description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
            container.viewContext.automaticallyMergesChangesFromParent = true
            container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
            return container
        } else { //less than iOS 13
            let container = NSPersistentContainer(name: CoreHelp.appName)
            container.loadPersistentStores(completionHandler: { (storeDescription, error) in
                if let error = error as NSError? {
                    fatalError("Unresolved error \(error), \(error.userInfo)")
                }
            })
            container.viewContext.automaticallyMergesChangesFromParent = true
            container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
            return container
        }
    }()

//Where CoreHelp. … is a struct containing different ids.

This works (at least on iOS 13+) but I’m having a hard time trying to figure out the correct way to set things. These are my main concerns:

  • Do I have to check/ask the user if they want to enable cloud sync or is it automatically checked based on their phone settings?

  • If the user doesn’t want to sync the data to the cloud, do I need to switch to NSPersistentContainer instead?

  • NSPersistentCloudKitContainer isn’t supported on versions released before iOS 13. How can I use CloudKit to sync/upload data saved by iOS 12 users (possibly still using CoreData)?

I read this stuff and more:
Using Core Data, iCloud and CloudKit for syncing and backup and how it works together
CloudKit and Core sync data between devices

but now the things are changed.

crost
  • 165
  • 1
  • 13

1 Answers1

1

The answer tl;dr is that you do it by doing a lot of independent work, that I can't personally guarantee will succeed. CloudKit with Core Data isn't supported on iOS 12 or lower.

The most likely scenario is to use CloudKit's JavaScript interface, probably with a custom server to host the JS code. The details of that are up to you but there's a Ray Wenderlich tutorial that will help you get started. Good luck.

If that doesn't work out, your best choice is probably the third party Ensembles framework instead of Apple's built in CloudKit support, for all iOS versions you support. It can work with iCloud or other sync services. I've used it with CloudKit and it was reliable.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170