Ok, I have a partial work around for the iCloud and Core Data bug.
First, a little background info. Everything here is based on my previous multi-doc iCloud example. As I mentioned in that post, there seems to be a race condition. If I have the device running on two apps, and I make a change on one app, every once in a while the second app will receive a NSPersistentStoreDidImportUbiquitousContentChangesNotification notification, but when I try to update the data, nothing happens. It seems like the notification is fired before the managed object contexts or persistent store coordinator have been properly updated.
Things seemed a little more solid with iOS 5.1. Now, at least, if I closed the document and reopened it, it would fetch the correct information. But it still wasn't perfect.
In the original project, when I received a notification, my app updated the managed object context as shown below:
// This should work, but seems to create race conditions
[moc performBlock:^{
[moc mergeChangesFromContextDidSaveNotification:note];
self.documentTitle.text = self.textEntry.title;
self.text.text = self.textEntry.text;
}];
In playing around, I discovered that if you reset both the parent context and the current managed object context, then reload your objects, you will actually get the correct value.
[moc performBlock:^{
id objectid = self.textEntry.objectID;
id parent = [moc parentContext];
[parent performBlockAndWait:^{
[parent reset];
}];
[moc reset];
self.textEntry = (TextEntry*) [moc objectWithID:objectid];
self.documentTitle.text = self.textEntry.title;
self.text.text = self.textEntry.text;
}];
Here, I'm just saving the object ID for my entry. Next, I clear both managed object contexts. Then I re-fetch the object for the ID and update my user interface. This works around the race condition, but you will lose any unsaved data in your managed object context--which is less than ideal. For the current app, this doesn't matter. But, for many applications, you may have to get the object IDs out of the notification and perform your own data merging.
In my tests, this has proven to be very reliable--depending, of course, on the quality of your internet connection. Updates occurred almost instantly when working at home. When testing it at Starbucks, I'd usually have to wait a minute or so for the update to propagate. So be patient when testing. I like to set a breakpoint in my update code that plays a sound then continues execution, just to alert me when the update is finally triggered.
However, I've now noticed another bug. If I make changes on both devices at the same time, then I can see that I trigger two updates--but neither device actually changes. They both keep their original data. This is true even if I shut down the apps and restart them. Of course, that's a pretty artificial test--so I think I'm OK ignoring that one. If you're making simultaneous changes on your devices, you kind of deserve whatever chaos you create.
Anyway, I know this is an imperfect solution, but I post it in the hope that it will inspire someone, and that we may be able to find a better solution to this problem.
Thanks,
-Rich-