Thursday, April 20, 2023


Ryan Ashcraft (tweet):

Last week, I published CloudSyncSession, a Swift library that builds on top of the CloudKit framework to make it easier to write sync-enabled, offline-capable apps.

I started CloudSyncSession over two years ago with the goal of replicating NSPersistentCloudKitContainer’s syncing behavior, without the Core Data hard dependency. Additionally, I wanted a solution that provided harder guarantees, more control, and more diagnostic information. I didn’t find an existing solution that met all of my requirements, so I (reluctantly) set out to build my own.

After years of refining this framework and fixing various bugs in my app, I’ve learned a lot about CloudKit syncing. You can glean some of my learnings by reading the code, but there’s a lot more that I felt I could share with a proper, technical blog post.

I love posts like this that are based on experience in the field:

CloudKit implements rate limiting. It has a special CKError code for this, requestRateLimited, but I’ve actually never seen an error with this code. In practice, rate limiting is indicated by serviceUnavailable (CKError 6, HTTP code 503).


Users want to know if their data is being synced properly. And from a customer support perspective, it’s invaluable to have logs and rich diagnostic information about the sync engine. Here are some diagnostics that I’ve found to be super helpful[…]


In an effort to make as much of the logic and behavior testable, most CloudKit-specific code is decoupled and/or mockable via protocols.


CloudSyncSession is not intended to be a drop-in solution to integrating CloudKit into your app. You need to correctly persist metadata and records to disk. In addition, you must use the appropriate hooks to convert your data models to and from CKRecords.

It does not support assets.

See also: Cirrus, CloudCore.


Comments RSS · Twitter · Mastodon

Leave a Comment