Under the Bridge

iCloud Cuckoo Land

Sometimes idioms are just too apropos:

live in cloud-cuckoo land

to believe that things you want will happen, when really they are impossible

A common sentiment lately is to find iCloud CoreData syncing a particularly cuckoo land, as you may have heard:

Tom Harrington: iCloud: State of the Union

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…

Daniel Pasco: The Return of NetNewsWire

As far as sync is concerned, we knew we would likely need an alternative to Google Reader as early as last year. At the time, the option that seemed to make the most sense was to embrace iCloud and Core Data as the new sync solution of choice. We spent a considerable amount of time on this effort, but iCloud and Core Data syncing had issues that we simply could not resolve…

Rich Siegel: The Gathering Storm: Our Travails with iCloud Sync

In general, when iCloud data doesn’t synchronize correctly (and this happens, in practice, often), neither the developer nor the user has any idea why.

Sometimes, iCloud simply fails to move data from one computer to another…

… While attempting to deploy iCloud sync on Mac OS X 10.7, we ran into a situation in which the baseline (a reference copy of the synchronization data) would become corrupted in various easily encountered situations…

…There’s no discernable consistency or rationale for when it says no and when it finally says yes … you can just keep trying, and eventually it might just work, or not.

Yikes! More discussion can be found at The Verge, and at Ars Technica, and here and there and everywhere, most wittily over at NSHipster; but let’s just settle for declaring it a given that people much better at this programming stuff than you are can’t make iCloud CoreData sync work, so neither will you.

However, it’s also getting close to a given these days that Your App Needs to Sync:

If your app deals with users’ data, building cloud sync into your app should not be a feature you bolt on to an app – it is the feature. It’s why you will beat competitors or lose hard to them. It’s what will make your app feel effortless, thoughtless, and magical. It’s what will gain a user’s trust, and once you have that, they will sing your app’s praises and never give it up. But to earn that trust, you have to account for sync at every step of the design and engineering of your app.

Developers have a number of choices as to how to build an app around sync. You can use iCloud, you can use a hosted service like Parse, or you can build a custom sync service for your app. Each solution has trade offs. So what should you optimize for?

The reality is that every app is different, and each sync system must cater to the data that is syncing. While it is certainly the most work, it’s my belief that you should optimize for control. You should have total and complete control over when and how your app syncs its data. You should be handling errors and conflicts, not abstracting them behind black-box middleware. Without this level of integration, you’re bound to a system that can fail unreliably, leaving users to figure out what went wrong. And when they try, it’ll be your app that feels broken.

Indeed. Read that whole article, it’s got the choices and tradeoffs discussed quite nicely.

For an enthusiastic exposition of the DIY extreme, check out Why Developers Shouldn’t Use iCloud Syncing, Even If It Worked:

You may think you’ll never want an Android or browser-based version of your app. But are you sure? Really, really sure?

You hope your app will be a hit. (If not, then quit writing it and choose something else.) If it’s a hit on iOS, it could be a hit on Android too — and you can bet that customers will ask for a web app version.

You don’t want to limit the success of your app just because you didn’t want to write your own server…

Well, there’s that. On the other hand, those of us who are not superhuman are challenged enough to write an app that works, never mind a server to go with it, and it limits the success of your app a good deal more to have it not released in a timely fashion, yes?

Splitting the difference, there’s the various backend as a service stuffies one could use; but just for the purposes of finishing off this post in a timely manner, let’s take it as given that your initial release is built around CoreData in the app, and you just want get sync working with that as quickly as you can with acceptable reliability. We’ve pretty much established here that iCloud’s out. What to do? What to do?

Well, here’s a few options that look worth a gander for that:

nothirst / TICoreDataSync is what Moneywell uses for Dropbox-based syncing:

TICoreDataSync is a collection of classes to enable synchronization via the Cloud (including Dropbox), or local wifi (coming soon), of Core Data-based applications (including document-based apps) between any number of clients running under Mac OS X or iOS. It’s designed to be easy to extend if you need to synchronize via an option that isn’t already supported…

AFNetworking / AFIncrementalStore eliminates sync problems by storing only in the cloud, which does make things simple if you can declare network access a requirement:

AFIncrementalStore is an NSIncrementalStore subclass that uses AFNetworking to automatically request resources as properties and relationships are needed.

Weighing in at just a few hundred LOC, in a single {.h,.m} file pair, AFIncrementalStore is something you can get your head around. Integrating it into your project couldn’t be easier–just swap out your NSPersistentStore for it. No monkey-patching, no extra properties on your models…

WasabiSync is a paid service that claims “Add seamless cloud synchronization to your Core Data based iOS app in less than an hour…”

Wasabi Sync monitors your existing Core Data persistent store and watches for when your application makes changes to it. When changes occur, Wasabi Sync serializes the changes and sends them securely over the cloud to the Wasabi Sync servers. Those changes are then propagated to the user’s other devices and written to their respective persistent stores.

Wasabi Sync requires almost no code changes to integrate with your app. The only things you have to do to start syncing are:

Add the Wasabi Sync SDK to your existing Core Data based project.

For any Core Data entities you want to sync, add a globally unique identifier to your models.

Specify that your syncable core data entities implement the WHISyncableObject protocol.

That’s pretty much it!

Simperium is another paid service whose flagship demo is Simplenote. Documented here:

Simperium iOS / OSX is a bit like iCloud: you can use it to easily move data among iPhone, iPad, and Mac versions of your app. But you can also:

  • Move data to non-Apple versions of your app
  • Retain control of your users and data
  • Build backend services
  • Earn money by selling more storage to your users
  • Brand these capabilities as your own

How it Works

Simperium can work with Core Data or JSON data stored in NSDictionary objects. As your users interact with your app, Simperium efficiently aggregates changes and moves them through our hosted, scalable service.

Changes are moved to and from Simperium as soon as possible. In the case where all devices are online, changes are moved in realtime. In the case where one or more devices are offline, data moves as soon as those devices come online. Conflicts can be resolved automatically.

Although the Simperium service hosts your app’s data, you retain control. You can host your own services that can see and store all data that moves through the system…

Interestingly, Simperium was recently acquired by Automattic:

As mentioned in our post on the Simplenote blog, Simperium has been acquired by Automattic! We’re really excited about this and what it will mean for the platform.

Automattic and WordPress are huge proponents of open source software so we’re happy to be able to go forward with our plans to open up the code, starting with the iOS and JavaScript client libraries. In the short term we’ll also be moving to faster hardware, so overall performance and stability of the hosted service should improve.

We’re going to keep expanding Simperium as a tool for building apps. Adding Simperium to apps that can work from a local datastore lets you automatically synchronize data across different instances and platforms. This way of building apps feels natural, a model where the developer can focus purely on the data itself, not networking or APIs. Synchronizing data is just part of the problem though. We’ll be adding better support for things like binary syncing and collaboration, along with a wider variety of client libraries…

One could be justifiably skeptical that interoperation with Core Data is likely to remain a priority at Simperium going forward. But maybe it will. And in any case, hey it’s open sourced so help out or fork it if you like.

Any experience with any of these solutions, Dear Readers? Or know of any CoreData-focused cloud syncing approaches we’ve missed here?


iCloud Complications, Part 1 and Part 2 and Part 3 and as She is Spoke

Does Core Data Sync Quack?

UbiquityStoreManager: Solving the iCloud for Core Data problem

Clear in the iCloud

Core data peer-to-peer synchronization

Use a Google Spreadsheet as your JSON backend if, you know, you don’t really need serious data at all…

objc.io #10: Syncing Data

(TL;DR: iCloud Core Data for 7.0+ only is usable!)

… or not: Ember and iCloud Core Data – “Now—three plus years after iCloud Core Data shipped—it sounds like they are giving up on it.”

How iComics Switched from Core Data to Realm in One Evening