As some of you know, I've spent a lot of time over the past year working with iCloud in Mac and iOS apps. Specifically, working with Core Data's built-in support for iCloud. I'm going to be doing a series of blog posts covering iCloud in various ways. Today I'm going to start off with an overview covering how iCloud is supposed to work with Core Data and a little about how it actually works in practice. This is an overview, a starting point. Nearly everything here should be read as having an invisible parenthetical "(more on this to come)".

My focus

Even though iCloud has been out for a while, there still seems to be a fair amount of confusion on the question of what it is. After seeing comments made at The Verge's article about iCloud I want to make clear where I'm coming from.

My main interest in iCloud is in getting it to work via Core Data in third-party apps. Public discussions (like comments at The Verge's article) often get a lot of "works for me!" comments from people who sync, for example, contacts via iCloud. That's great, I do it too, and it seems to work, but it's not what I'm writing about. The confusion here comes from the fact that "iCloud" covers a lot of ground. Some of it works reasonably well, other parts less so. As Matthew Panzarino explains at TNW, the "iCloud" presented to end users is very different from the one presnted to developers.

There's also often confusion with Dropbox's services which, for the most part, are almost entirely irrelevant to getting Core Data to sync between devices. I use Dropbox heavily and I like it, but it's not useful in getting third party Core Data stores to sync.

The Promise

The framework provides a remarkably simple looking approach to syncing. As described at WWDC and other places, the basic approach is

  1. When loading your persistent store, include a couple of options to tell NSPersistentStoreCoordinator how you want to use iCloud.
  2. Listen for notifications of incoming changes from the cloud, so that you can update your UI with the new information.

There are numerous other details to think about-- duplicate detection, cases where your custom managed object code gets run unexpectedly, and others. In principle though, it's straightforward.

Having done this, your app would then automatically sync changes between different devices that use the same iCloud account. Users would have their data available transparently on every device.

The Reality

iCloud-YUNO

And then... One day you call -addPersistentStoreWithType:configuration:URL:options:error: and it fails, with an incomprehensible error about not being able to upload (or sometimes download) a file named baseline.zip. Or else, some other equally incomprehensible error relating to undocumented internal classes like PFUbiquityImportScanOperation or PFUbiquitySwitchboardCacheWrapper. You've never heard of baseline.zip, and you weren't attempting to upload or download anything. Your app doesn't have access to iCloud at this point, but what's worse, you also don't have access to your local data store, and you have no recovery path for either problem. Worst of all, you did not actually do anything wrong, and there's nothing you can do to fix it. Try again, and better luck next time.

Or maybe one day the user launches System Preferences on their Mac, sees your app in the iCloud section, and clicks the "delete all" button for your app's data. While your app is running. And your app doesn't get a notification. And your app doesn't even run on Mac OS X, but gets nuked remotely anyway because iOS apps are listed too.

Or something more subtle, like, out of thousands of entities in a particular data store, most of them sync to another device, but some inexplicably disappear. Or show up, but are corrupt. Even if iCloud seems to be working, you'll want to be examining the synced data very closely before shipping.

There are two core problems at work here:

  • Syncing is hard. Developers know this. Syncing Core Data stores across multiple devices is a difficult problem to solve.

  • Syncing is a headline feature for iOS. Apple promotes syncing to users. It's up to developers to implement it. But those who try often find that the results are unshippable.

This puts software developers in an impossible position. Users hear about how great iCloud is and how apps can use it to sync their own data. They quite reasonably wonder why your app isn't using it. Syncing data is a great idea, Apple gives you iCloud, why aren't you using it, dammit? But if you did use it, the app would be so unreliable that users would (again, quite reasonably) complain that it was a steaming pile of shit.

So what happens now?

I'd really like to see this work. I've written software for Apple's platforms for a long time, and I want it to succeed. I know a lot of other would-be iCloud developers feel this way too. But it's just about 18 months since iCloud was released to the public with iOS 5, and several developers have publicly responded to the situation by giving up. Some may look for alternate sync schemes. Others are just skipping sync for now and hoping for improvement in future updates.

There are certainly arguments for using non-iCloud syncing services, such as those covered by Brent Simmons. But "iCloud doesn't work" shouldn't be one of them. Sadly, stories like Black Pixel's are becoming more common. Even the best developers in the industry throw up their hands in frustration and move on.

Will iCloud recover? It's hard to say. I certainly expect it to improve in future updates. But there's a major trust deficit regarding iCloud at this point. It's sounded really good in the past, so if it sounds really good in the future, people will still be skeptical. It was supposed to be much better in iOS 6 and Mac OS X 10.8. In practice it was... less bad? But still not ready for prime time.

After having spent huge amounts of time working on something that was supposed to be (relatively) easy, it will be hard to convince people to try again. Especially those who find alternate sync schemes that do the job . For them the question won't be, is iCloud good enough to use? It will be more like, is iCloud good enough to ditch something that works and start over? That's a much tougher standard to meet.

Further reading

I'll be getting into more of this over the next few weeks but in the meantime there here are a couple of really good articles describing the situation that have come out in recent days: