I like Core Data too. And I like CloudKit.

Sounds like Project has a to-many relationship to Pattern, and a Pattern has a to-many relationship to Project. The Core Data delete rules will be to nullify in both directions.

For your Pattern image files, you could create an ‘imageData’ attribute of type NSData and choose the ‘use external storage’ option. This tells Core Data to write your data as a blob to the database. The nice part is if the image is large (over ~150K) the data is written to disk as an optimization. Either way it’s transparent to you – you’ll always get and set an imageData property that is of type NSData.

This is great approach – super simple. HOWEVER, I have run into performance issues during database migrations when you have a large number of these Pattern objects (with large imageData properties). Apparently during migration Core Data copies each of these files to a new location for the new store, and it is slow.

If you think this could be the case for your users, then it would be better to save the image data to disk yourself, and store the path to the file as an ‘imagePath’ string attribute on Pattern. You’re doing the same thing Core Data does, but you lose a couple things – namely the atomicity of the save and deleting the file when the object is deleted.

Since this is a brand new project, I would suggest letting Core Data handle it for you. You’ll be up and running faster. If it proves to be a problem one day, it’s not a huge problem to fix.

Now, with regards to CloudKit, I think it’s fantastic. I’ve used it in four projects to sync with Core Data and couldn’t be happier. But there is no built-in syncing mechanism between Core Data and CloudKit. You have to replicate your Core Data model in CloudKit. So you’ll need methods to convert a Pattern object to a CKRecord, and vice versa.

CloudKit has a really nice sync API – you give it a token and it will tell you about all additions, deletes, updates, etc. since the last sync. You update your core data objects from these records.

And naturally, you tell CloudKit about all the changes on your side as well so other devices pick up the changes.

I would suggest reading Kugler and Eggert’s fantastic book on Core Data (in swift) https://www.objc.io/books/core-data/ . They talk about an approach to syncing (using any cloud storage) that works very well. One of the authors worked at apple on converting the iOS Photos app to using Core Data, so they kind of know their stuff.