How to Sync data between two devices using Core Data & iCloud? How to Sync data between two devices using Core Data & iCloud? swift swift

How to Sync data between two devices using Core Data & iCloud?


This how I have mine setup and it syncs my core data and it keeps changes synced.

enter image description here

This from my AppDelegate.

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.    // Create the coordinator and store    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("APPNAME.sqlite")    var error: NSError? = nil    var failureReason = "There was an error creating or loading the application's saved data."    // iCloud store    var storeOptions = [NSPersistentStoreUbiquitousContentNameKey : "APPNAMEStore",NSMigratePersistentStoresAutomaticallyOption: true,        NSInferMappingModelAutomaticallyOption: true]    // iCloud storeOptions need to be added to the if statement    do {        try coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL.fileURLWithPath(url.path!), options: storeOptions)    } catch var error1 as NSError {        error = error1        coordinator = nil        // Report any error we got.        var dict = [String: AnyObject]()        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"        dict[NSLocalizedFailureReasonErrorKey] = failureReason        dict[NSUnderlyingErrorKey] = error        error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)        // Replace this with code to handle the error appropriately.        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.        NSLog("Unresolved error \(error), \(error!.userInfo)")        abort()    } catch {        fatalError()    }    return coordinator}()    // MARK: - iCloud// This handles the updates to the data via iCLoud updatesfunc registerCoordinatorForStoreNotifications (coordinator : NSPersistentStoreCoordinator) {    let nc : NSNotificationCenter = NSNotificationCenter.defaultCenter();    nc.addObserver(self, selector: "handleStoresWillChange:",        name: NSPersistentStoreCoordinatorStoresWillChangeNotification,        object: coordinator)    nc.addObserver(self, selector: "handleStoresDidChange:",        name: NSPersistentStoreCoordinatorStoresDidChangeNotification,        object: coordinator)    nc.addObserver(self, selector: "handleStoresWillRemove:",        name: NSPersistentStoreCoordinatorWillRemoveStoreNotification,        object: coordinator)    nc.addObserver(self, selector: "handleStoreChangedUbiquitousContent:",        name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,        object: coordinator)}


A difference I see between what works for me and your code is:

1) I don't see where you've added an observer for the NSPersistentStoreDidImportUbiquitousContentChangesNotification such as in the code:

let nc : NSNotificationCenter = NSNotificationCenter.defaultCenter();let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegatenc.addObserver(self, selector: "dataUpdated:",        name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,        object: self.managedObjectContext?.persistentStoreCoordinator)

2) In my code in the function that catches the notification (dataUpdated in this case), it resets the managed objext context with the following code before it updates the display to show the new data:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegateif let managedObjectContext = appDelegate.managedObjectContext {     managedObjectContext.reset()}

After resetting the managed object context, I fetch the entity again using the code:

let fetchRequest = NSFetchRequest(entityName: "ClassNameHere")let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)fetchRequest.sortDescriptors = [sortDescriptor]let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as! [ClassNameHere]