After the last effort I tried the following things:
First, I tried to stand-up my own Core Data stack by trying to piece together the code from MagicalRecord’s setup method. I was doing fine until I ran into the code that set a flag in MagicalRecord to indicate that iCloud was being used. It was a private method. I need to look to see where that flag is used, if it turns out it is used inside MagicalRecord, then I will need to stand-up my own stack from the ground up. I’m wondering if I could do that and then set the right final objects on MagicalRecord and it would work.
I next deleted the app from my device. In the end I lost all my stored records. But the app did come back and I was again able to use it (at the current model version number I was on). I still need to try a sane migration.
I found out auto-migration is the only thing supported for Core Data iCloud sync. But I still had this issue where my local stores were not syncing. I ran across an article that talked about a method called a NSPersistentStoreCoordinator method, removeUbiquitousContentAndPersistentStoreAtURL. Which the documentation says will delete all ubiquitous content for all peers for the persistent store at a given URL and also deletes the local store file. (http://www.objc.io/issue-10/icloud-core-data.html)
So I set this up and on my first device as follows and ran it:
class func resetCloudStore(completion: ((Void) -> Void)?) {
let containerId = getCloudContainerId()
let cloudURL = NSPersistentStore.MR_cloudURLForUbiqutiousContainer(containerId)
var error: NSError? = nil
let contentNameKey = getUbiquitousContentNameKey()
let options = NSDictionary(objectsAndKeys: contentNameKey, NSPersistentStoreUbiquitousContentNameKey)
let storeURL = NSPersistentStore.MR_urlForStoreName(MagicalRecord.defaultStoreName())
MagicalRecord.cleanUp()
let result = NSPersistentStoreCoordinator.removeUbiquitousContentAndPersistentStoreAtURL(storeURL, options: options, error: &error)
NSLog("Finished deleting ubiquitous store with result \(result)")
}
To make this work I created two helper methods:
getCloudContainerId() - returns a String of this form "iCloud.\(bundleIdentifier)"
getUbiquitousContentNameKey() - returns the same String we used when setting up MagicalRecord
I also added a completion block which I am not using right now but intend to later.
The result was the local store went away, so I lost all my local data. I then went to my second device and did the same. What happened next was unexpected. Within a few seconds the first device got all of the data from the second device. Syncing was now working again. That isn’t what I expected. I had expected that I would have had to enter my data all over again. It seems somewhere the data was stored, got sync’d to the cloud account and then sync’d to all the attached devices.
I’m now at a point where I want to be able to turn on and off iCloud syncing. Actually, I only want to be able to turn it on (never to turn it off again). Reading more online I am still trying to figure out how this works. There could be a book written just on Core Data sync. There probably should be one written. I’d buy it if it was any good. It would have to only cover the the new API though. I feel like that is what the Ensembles guys are doing, just wish the book was more than 60% complete (as of March 28, 2015). That would probably swing my decision to use their package.
At any rate, back to the issue at hand. How do you do a one way transition to cloud syncing? Here is what I think I know so far. When the Core Data stack is stood up (I’m using MagicalRecord but I don’t think that really matters much here) there is a local “backing” store and a cloud store (the ubiquitous store). Any time I save a NSManagedObject it goes to the local “backing” store and eventually is sync’d to the cloud store.
When I do the same setup but only go to the local store (i.e. don’t add the icloud options) I get an empty local store. My hunch was that I was getting two different stores for the local store depending on whether I had sync enabled or not. After doing a good bit of debugging I confirmed that was the case as the URL’s for the local store and local “backing” store didn’t match between sync versus no-sync modes.
In the same article I referenced above there is a section on how to turn iCloud sync on and off. I have started down that road. So far it’s not working. It’s kind of interesting, for a long time I could not get Core Data iCloud sync-ing to work, now I can’t get it to stop!!
No comments:
Post a Comment