I can't handle this problem, I'm trying to integrate iCloud and Core Data to my app and I stuck with iCloud synchronization part.
My complete scenario:
- Local core data storage seeded with initial data
- Later the app ask the user about iCloud or local data stoge
- If user choose iCloud, current local storage migrates to iCloud store
- After migration, context and persistent store coordinator is reloaded with iCloud Store
- Refetch data from new context (Trouble here)
If we take away discussion about migration and focus on loading persistent store coordinator with iCloud, I think that the problem is related to
NSPersistentStoreCoordinatorStoresDidChangeNotification
event.
I just don't understand it. In every article that I read, I saw something like: "reload you UI here". But it doesn't work for me.
Reload coordinator function
func configureContext() -> NSManagedObjectContext? {
// Create the coordinator and context
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
//remove all observers from "previous" coordinator
deregisterForStoreChanges()
//and register them for new one
registerObservers(persistentStoreCoordinator: coordinator)
do {
//storeSettings.url = applicationDocumentsDirectory.URLByAppendingPathComponent("iCloud.sqlite")
//storeSettings.options = [NSPersistentStoreUbiquitousContentNameKey:"iCloudProject"]
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeSettings.url, options: storeSettings.options)
} catch {
//Here was standard error handler I didn't changed it, but removed for listing
abort()
}
persistentStoreCoordinator = coordinator
let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
//not quite sure about the next string, didn't test it yet
managedObjectContext.mergePolicy = NSMergePolicy(mergeType:NSMergePolicyType.MergeByPropertyStoreTrumpMergePolicyType )
//tried to refetch my records here but, with no luck.
//refetchUIRecords()
return managedObjectContext
}
And my NSPersistentStoreCoordinatorStoresDidChangeNotification
event func
func persistentStoreCoordinatorDidChangeStores(notification:NSNotification){
if notification.userInfo?[NSAddedPersistentStoresKey] != nil {
print("-----------------------")
print("ADDED")
print("-----------------------")
//deduplicateRecords()
//if iCloud -> refetch UI
if NSUserDefaults.standardUserDefaults().boolForKey("iCloud"){
self.createTimer()
}
}
print("Did Change")
}
Create timer function is just a function which wait for 1 secods before actual refetching and refreshing UI.
The problem
When we reach step 4 from my scenario, and call configureContext function, I see this in the console:
2016-04-12 13:31:27.749 TestingiCloudProject[2052:1142902] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity: mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject
Using local storage: 1 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea>
Did Change
Did Change
-----------------------
ADDED
-----------------------
Timer
Did Change
Refetch
Refetching...
Number of records after fetch: 1 //must be more than 1
2016-04-12 13:31:30.090 TestingiCloudProject[2052:1143055] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity: mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject
Using local storage: 0 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea>
As you can see my fetch request executes before Using local storage: 0
and that's why I'm recieving records from the local storage (1 record) not iCloud (which contains more than 1).
I don't understand when to refetch my records. I take timer part from this great source for all who want to know more about Core Data and iCloud. But, 1 second isn't enought, 2 seconds is work as I want, but what if iCloud store will be bigger than mine, or network connection will be worse than mine, I don't think that timer is the way.
I hope somebody already face this trivial problem.
EDIT
I didn't find any help from Apple dev forum and SO, so I activated my code tech support token, I hope they can help me. As soon as I'll solve my problem I'll write an answer. But, if you, who read this question, know the possible answer, post it now.