I like to understand things that wrapper and APIs like to obfuscate. CoreData especially in combination with CloudKit was very overwhelming for me. And it still is. However I could clear some things up for me.
Since I preferred Apple doing some heavy lifting, posts and tutorials that "built the whole Core Data Stack from scratch" confused me. I wanted to understand and expand what was already there.
OR (assuming the app already uses CoreData, because if not you'd have to add the whole PersistenceController
)
NSPersitentContainer
in PersistenceController
with NSPersitentCloudKitContainer
container.viewContext.automaticallyMergesChangesFromParent = true
in PersistenceController.init()
as the last line+
if needed) - you could also use an existing one and share data between apps.You're done.
Attention: iCloud sync in simulator is wonky at best. Use physical devices.
An iCloud container simply put is like a directory in iCloud where all the cloud stuff of your app reside. You're using an NSPersitentCloudKitContainer
? It's synced to the iCloud container. Using multiple? A single one with multiple configurations? They're all there.
The iCloud container is like the sandbox of the app on the device but in the cloud.
NSPersistentContainer
An NSPersistentContainer
is a class that handles all your interaction with a database (or multiple database files, see: configurations).
NSPersistentCloudKitContainer
An NSPersistentCloudKitContainer
also handles all your interaction with a local database and it also handles syncing it to and from the cloud.
Usually there's a file called Persistence.swift
in your project. Or your PersistenceController
class is created elsewhere.
This PersistenceController
instantiates a persistent container that connects to a .sqlite
-database (which is defined by a .xcdatamodeld
file) in your project. You reference it by name: NSPersistentContainer(name: "MyDataModel")
- you need a MyDataModel.xcdatamodeld
for that to work.
You could copy the whole code and instantiate a second container referencing another file.
An NSPersistentCloudKitContainer
would then sync both persistent containers (read: files) to your iCloud container (read: sandbox).
Conveniently it would simply sync it to the first iCloud container in the list of iCloud containers checked in the iCloud capability.
You could want to separate topics in different databases not just different tables. For clarity or so. I.e. an app that stores your refrigerator content and your car parts. Similar database structure but different enough that two database files make sense.
If you'd want to access a private and a public part of database in an iCloud container, you'd have to use NSPersistentCloudKitContainerOptions
and configurations.
Of course you could use could use configurations for that silly use case above too.
NSPersistentCloudKitContainerOptions
and configurationsSay you want to connect a NSPersistentCloudKitContainer
to a different iCloud container than the first in the list you marked with a checkmark.
Or you'd like to connect the public and private records in the first (or any other) iCloud container in said list.
That's what NSPersistentCloudKitContainerOptions
is for.
Further Reading: https://patmalt.medium.com/end-to-end-encryption-and-cloudkit-with-coredata-part-1-67bfbe467bc
Simply use a NSPersistentContainer
and omit the lines below from the code above.
Yes. Loads. It's a highly complex topic. I don't understand all of it yet.