iCloud: A Black Box That Needs a Few Dials on It

One of the challenges we faced with Stashpix was how to let users control their content while remaining anonymous, and retaining that control across repeated installations and multiple devices.  We also needed to be able to ban abusive users.

Anonymous control isn’t too hard; you can merely generate a UUID and make that the key to everything the user does.  But that key is stored in the app’s sandbox, and if the app gets deleted, so does the ID.

It’s also specific to the device on which the app was launched.  Previously, we captured the device’s UDID and associated it with the user’s UUID, so we could recover the UUID if the app was deleted.

This still didn’t give the user control of the same stashes on all of his iOS devices.  I was preparing to implement a solution for this; it would involve the user manually identifying a secondary device as having the same owner as the first, through a special procedure that would have the server return the “master” UUID to the secondary device and consolidate the database entries to that UUID.  Then iCloud came along and provided what looked like an excellent solution to the whole dilemma.

We use iCloud’s key/value store to give a user control of his stashes across all of his iOS devices. This works well, but as others have documented, iCloud has a way to go before it’s a mature solution.

Right off the bat, iCloud calls simply didn’t work.  Lacking any real feedback mechanism, they simply returned “NO”.  I finally had to open a support incident with Apple.  The technician gave me a couple of commands to activate iCloud logging, and simply executing these commands broke whatever logjam had prevented iCloud from working.  I didn’t change a line of code or single project setting.  To this day we don’t know what the problem was.

Another important tidbit about iCloud is that your app can be throttled, and this too will cause your iCloud usage to mysteriously fail.  The documentation does not convey this; it simply says that frequent accesses will make it more likely that updates will be deferred. But the calls in code will fail.  Apple refused to tell me what the threshold is for throttling. Can I step through my code twice in a minute?  Five minutes?  Of course there’s no API call to find out if you’re being throttled.

There’s also no apparent way to find out if your local key/value store has EVER synced with iCloud. There is an “initial sync” notification that you might get if the user’s iCloud account contains a different value for a key than the local store, but what happens if the user’s iCloud store is empty? What if the local store is empty?  Does that notification still occur?  The documentation doesn’t say.

And not surprisingly all the iCloud calls are asynchronous, so the app has to find some way of operating while it waits to hear back from iCloud (if indeed it ever does).  In our case, if we don’t get the user’s ID from iCloud, we have to generate a new one and operate the way we did in previous versions.  If we subsequently get a different ID from iCloud, we have to reconcile anything the user might have done with the temporary ID.

Apple does admonish programmers not to store critical info in iCloud, but they go on to give examples that do require immediate results from iCloud in order to be useful.  For example, you might want to store which page of an article the user was reading on one device, so he opens right up to that page on another.  Or where the user was in the movie he was watching on his computer, so we can go to that spot when he switches to his iPad. Since we don’t know how long it might take to hear back from iCloud, your app may need to implement quite a bit of state-checking to handle a delayed return from iCloud gracefully.

Further complicating this are cases where the user activates iCloud after using the app for a while, or even changes the iCloud ID under which the device is operating.  We have a lot of logic to compare user info stored in user defaults against the “ubiquitous key/value store”; and then we have to figure out if the local key/value store is synced with iCloud’s.

There’s a pretty good rundown on the problems developers have faced with iCloud thus far here: http://www.macstories.net/stories/iclouds-first-six-months-the-developers-weigh-in

Update 3/31/13: More developers rail against the state of iCloud:
http://arstechnica.com/apple/2013/03/frustrated-with-icloud-apples-developer-community-speaks-up-en-masse

Apple needs to get the API in shape for this thing, because it could be a great resource for developers.

Comments are closed.