0 Replies
      Latest reply on Aug 13, 2019 7:54 AM by alienspaces
      alienspaces Level 1 Level 1 (0 points)

        There are a few things about how Core Data 4 Cloud Kit initializes that I'm stuggling to understand. I've spent most of the day finally getting a schema initialized on the server, and learnt a few things along the way.

         

        Firstly, even though I have a Default configuration in my managed object model, and it has been there from day one with the option "Used with CloudKit" checked for true, if I create an `NSPersistentStoreDescription` and set the configuration property to "Default", when I try to load the stores, it will fail, saying "Unable to find a configuration named 'Default' in the specified managed object model.". If I inpsect the debug description for my ManagedObjectModel instance, it does indeed not have any reference to the string "Default" in it (I'm not sure if debugDescription is actually printing out the configuration names however). Why does this fail? I can only get my store loaded and the schema initialized if I remove the code that sets the configuration name to "Default".

         

        The next thing that tripped me up was the NSPersistentCloudKitContainerOptions property on the store description. Considering that the only property on that class is now gone, so you no longer need to perform `options.shouldInitializeSchema = true`, I incorrectly assumed that I'd no longer need to even create and set a NSPersistentCloudKitContainerOptions instance on my store description, because all it really holds is the containerIdentifier. Why would I need to specify a container identifier if the system is going to fetch the first iCloud Container Identifier out of the entitlements file and associate it with the Default configuration which I'd (clearly incorrectly) assumed would be automatically associated with CloudKit and my "Default" entitlement container identifier.

         

        Below is the code I was using. It's mild playground refactor of my real code, but it's quite straightforward.

         

        // Instantiate the Managed Object Model
        let modelName = "CloudModel"
        let url = Bundle.main.url(forResource: modelName, withExtension: "momd")
        let mom: NSManagedObjectModel = NSManagedObjectModel(contentsOf: url!)!
        
        
        // Define the Cloud Store Description
        let storeURL = URL(fileURLWithPath: "Cloud.sqlite",
                           isDirectory: false,
                           relativeTo: NSPersistentContainer.defaultDirectoryURL())
        
        let cloudStoreDescription = NSPersistentStoreDescription(url: storeURL)
        cloudStoreDescription.shouldAddStoreAsynchronously = true
        cloudStoreDescription.configuration = "Default" // this will cause loading to fail with an "Unable to find
        // a configuration named 'Default' in the specified managed object model." error
        
        // Add a container options instance to the description, because without it, loading will fail with 
        // "Couldn't initialize CloudKit schema because no stores in the coordinator are configured to use CloudKit"
        var cloudKitOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "com.example.container.identifier")
        cloudStoreDescription.cloudKitContainerOptions = cloudKitOptions
        
        // Create the Container for the Cloud Store
        let container: NSPersistentCloudKitContainer = NSPersistentCloudKitContainer(name: modelName, managedObjectModel: mom)
        container.persistentStoreDescriptions = [cloudStoreDescription]