Here are some references from around the web on how to implement CloudKit syncing. It will be added to…
As I Learn CloudKit Syncing by Eric Allam (added 5th January 2017)
Probably my favourite tutorial so far, Part 1 follows the example given in the Advanced CloudKit talk from 2014, unfortunately the talk and this tutorial doesn’t get as far as using push notifications via a CKRecordZoneSubscription and resorts to fetch only. It correctly uses CKFetchRecordChangesOperation for this, however it contains a mistake in part 4. It says that only changed properties are included in the CKRecord given by the recordChangedBlock, in fact the full record is included by default, and it now also supports a desiredKeys in the newer version of this class named CKFetchRecordZoneChangesOperation. It correctly identifies using NSOperation dependencies as the right approach for queuing related operations, however in seek of queue error handling Eric looks to the Advanced NSOperations talk and corresponding open source project, which unfortunately is of a different design to CloudKit NSOperations and he hits some problems.
Seam – Seamless CloudKit Sync with CoreData (added 5th January 2017)
This project provides tight coupling with CoreData that seems to go against Apple’s designs of keeping frameworks more loose. For example, it wraps conflict handling which might be something the developer requires full control over. It’s always the same with wrapping, you end up hiding away something needed and then having to write more code to expose it again. Opting certain entities out of syncing requires extra effort, and it appears to support only an all-or-nothing sync, rather than say just up or down. The project was coded in Swift so unfortunately fell victim to the constant syntax changes of the language, and has been left broken on Swift 3.0. Furthermore, NSOperation is designed around returning errors rather than exceptions that Swift uses, I’m not sure how well the developer handles this but it does seem a potential area of weakness.
CloudKit + Core Data + NSOperations – Syncing by Nick Harris (added 5th January 2017)
This is the top tutorial on Google for CloudKit syncing, but sadly has mistakes and leaves many unanswered questions. Uniquely, Nick uses a record zone per record type which obviously isn’t the right approach for these kind of records, he realises this later, and the reason is that CKRecordZoneSubscription can be scoped to a recordType. Another mistake is by subclassing CKFetchRecordsOperation to perform processing, however he strangely does then use correctly use NSOperation dependencies for the sync method. One interesting approach is to use a separate entity to store deletes, so that the real entity can be deleted as normal rather than just soft deleted; this has the advantage that predicates don’t need the additional where status != deleted. There doesn’t appear to be any error handling if any one of the operations fails, furthermore the synchronous processing NSOperation just fatal errors if anything goes wrong with the Core Data method calls. I believe if he had access to an asynchronous NSOperationQueue class that supports errors and cancellation it would have helped a lot. Written in Swift so again falls victim to syntax changes.
Apple CloudKit Engineer on Stack Overflow (added 5th January 2017)
A developer named farktronix gives great insight into the inner workings of CKFetchRecordZoneChangesOperation on the server. From the name of the class you might think that this returns all changes or deletes, which at first glance would appear far too much data to be useful for an initial sync, so for example, you might think instead to query to get the first set. However the developer states that the server coalesces changes before sending them (which gives the bug being discussed), this means that if a record was created and then deleted, the server is smart enough not to send either of those events in the fetch changes operation. This is a really great piece of insider info, and hopefully this user shares more in the future.