In this latest installment of my iCloud series I'll be taking a look at real world iCloud. Not in the sense of how you should write code to make effective use of iCloud, but in the sense of finding out how people are actually using it in real shipping apps. This was one of my primary purposes in writing momdec, my Core Data model decompiler, and I'll use it here to see what turns up. I included a rough date in the title of this post because I hope it will be worth revisiting one day.

Who's using iCloud with Core Data?

Possibly, some apps you already have are already using iCloud with Core Data in at least a limited sense. You could look in Settings (on iOS) or System Preferences (on Mac OS X) and try to guess which apps are using this particular iCloud API. But it's surprisingly easy to identify the ones using iCloud via Core Data if you have a Mac that uses the same iCloud account (even for iOS apps), because:

  1. On Mac OS X, iCloud is "greedy". It downloads all of your account's data from any apps as soon as the data is available for download. This happens even if those apps aren't installed on the Mac. Even if they can't be installed on the Mac because they're iOS apps, in fact.

  2. Apps that use iCloud with Core Data have a characteristic signature that makes them easy to identify on a Mac.

In short, if you want to know which of your current apps use iCloud with Core Data, do this on a Mac:

find ~/Library/Mobile\ Documents -name baseline.zip

The results may not contain the exact app name but it's generally pretty easy to parse the file paths. For example:

/Users/tph/Library/Mobile Documents/243LU875E5~com~apple~movietrailers/
    .baseline/com.apple.movietrailers.4/13lRaLslGNDGXwquwOAXIr0mgPPB7Df17z6ip9rwJ5Q=/
    baseline.zip

This file is the starting point when looking at an app. Core Data with iCloud is transaction based. The baseline.zip file is the Core Data iCloud baseline, which is the starting point for those transactions. It contains several files:

  • gcmodel: The compiled model file in the usual format, readable using NSManagedObjectModel and decompileable via momdec.
  • model: Appears to be the same model compiled to a different format, not readable using NSManagedObjectModel. I'm not sure what it's purpose is. I'm guessing that PFUbiquityBaseline (undocumented) uses it but I don't know why a second format is needed.
  • metadata: A PFUbiquityBaselineMetadata object, archived via NSKeyedArchiver. I haven't been able to unpack this since the class is undocumented.
  • storeFilename: Text file containing the data store file, something like Foo.sqlite.
  • storeFilenameToData: Dictionary containing the baseline data store file used when replaying transactions. There's one key, which is found in storeFilename. Its value is the SQLite data file.

In this post I'll be sticking to Apple's use of iCloud + Core Data, but they're not alone. The only Apple examples I've found are the iTunes Movie Trailers app and the system-wide spelling dictionary. There are other examples from third party developers, and you might be interested in taking a look.

Getting the data model

As a result of some recent commits to momdec, it's possible to use it directly with an iCloud baseline.zip file. When used this way, momdec unzips the file into a temporary directory, locates the data model and sets its name (using gcmodel and storeFilename, described above), and then proceeds as usual to decompile the model. You'd get the model for the movie trailer app, written to /tmp/, with something like this (wrapped to fit):

momdec ~/Library/Mobile\ Documents/243LU875E5~com~apple~movietrailers/.baseline/
    com.apple.movietrailers.4/13lRaLslGNDGXwquwOAXIr0mgPPB7Df17z6ip9rwJ5Q\=/
    baseline.zip /tmp/

(your path to baseline.zip will vary)

This produces a model at /tmp/TrailersCloud.xcdatamodel, which Xcode will happily open.

The models

So what do the models look like? Here TrailersCloud.xcdatamodel:

TrailersCloud.xcdatamodel

And here's the spelling dictionary model:

CloudUserDictionary.xcdatamodel

The attribute types are exactly what you'd expect based on the names.

Neither of them turns out to be very interesting. Trailers has two entities and the spelling dictionary just one. Neither has any relationships. But this lack of interesting detail is, really, the interesting part. In the only two examples I've been able to find of Apple using iCloud with Core Data, the data models are almost trivial. Less complex, in fact, than you'd expect in a decent introduction to using Core Data.

I found a more interesting example of a data model from a third-party developer that, while not exactly complex, is certainly less trivial. In this case the model has four entities linked by three many-to-many relationships. I don't think I've heard the author weigh in on how well iCloud has worked in practice, though. I'm going to make some inquiries and see what I can find out, but for the moment I prefer not to name them. Some of you may have this app and might find the model for yourselves.

So what does all this tell us?

A couple of insights that may be of interest if you're using (or attempting to use) iCloud's Core Data API:

  • You're almost certainly using it in a more complex manner than Apple. That's kind of surprising, given the diverse array of software Apple produces.

  • If these two apps are actually the only examples from Apple, your app's data is almost certainly more important to the user than the data Apple's apps sync via this API. If iCloud just completely flakes out for either of these data models, the worst that would happen is that the user's favorite movies or theaters might be lost, or that iOS's spelling correction might not pick up on their commonly used words. Now, any loss of user data is a very bad thing indeed, but at the same time it's not like anyone would lose their financial history or a creative work of any kind. At worst, a total loss of user data in these models would be a minor inconvenience, but this may not be true of your app.

Incidentally...

Another handy and relatively new feature of momdec is the ability to scan a app's bundle, locate its data model, and decompile it. As is this works on Mac apps. For iOS apps, if you use iTunes and have apps download to your Mac, the app bundle is wrapped up in a .ipa package in ~/Music/iTunes/Mobile Applications/. But an ipa is just a zip file, so getting the app bundle is straightforward. I'm planning to add automatic ipa processing to momdec but haven't gotten to it yet.