On my last post I added Core Data to my SwiftUI Multiplatform project, I a get some feedback on twitter and now I can show your how to add CloudKit to Synchronize data between your devices
So first of all I wanna say thanks to Malcom Hall
He give me a better approach to the Core Data class so now we are using the new @StateObject
Step 1
so first of all we are gonna make a little refactor to our code on the PersistentCloudKitContainer.swift Class
Right now the class looks like this
//
// PersistentCloudKitContainer.swift
// ruleOfThree
//
// Created by Francisco Misael Landero Ychante on 27/06/20.
//
import CoreData
public class PersistentCloudKitContainer {
// MARK: - Define Constants / Variables
public static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: - Initializer
private init() {}
// MARK: - Core Data stack
public static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "ruleOfThree")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
// MARK: - Core Data Saving support
public static func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
So first of all we are gonna make the class conforms to ObservableObject
...
public class PersistentCloudKitContainer: ObservableObject {
...
Next we are gonna delete the follow lines
...
// MARK: - Define Constants / Variables
public static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: - Initializer
private init() {}
...
next we are changing or var persistentContainer to be lazy and also to return a NSPersistentCloudKitContainer
...
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "yourModelDataName")
...
also we are adding the next unwrapper
...
guard let description = container.persistentStoreDescriptions.first else {
fatalError("No descriptions found")
}
description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
...
So this is what we have now
import CoreData
public class PersistentCloudKitContainer: ObservableObject {
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "ruleOfThree")
guard let description = container.persistentStoreDescriptions.first else {
fatalError("No descriptions found")
}
description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
NotificationCenter.default.addObserver(self , selector: #selector(processUpdate), name: .NSPersistentStoreRemoteChange, object: nil)
return container
}()
}
Next we are gonna make a little changes on or @main
import SwiftUI
import CoreData
@main
struct ruleOfThreeApp: App {
@StateObject var coreData = PersistentCloudKitContainer()
var body: some Scene {
WindowGroup {
ContentView().environment(\.managedObjectContext, coreData.persistentContainer.viewContext)
}
}
}
Cool now we can add CloudKit
Step 2
adding Cloud Kit
So now we go to our Project file and were we have our targets we chose iOS, then singning & Capabilities

Now on the button + capability we chose iCloud

Once added we select the CloudKit checkbox and then on containers we select our container if you don’t have one make a new one just write the name and its ready.

We make the same for macOs
Step 3
Now we go to our Data Modelo and under Configurations > Default we open the inspector on the lateral side an chose Use with CloudKit

And that’s all, we now can run or simulator and test, you need to login on the simulator with the same iCloud account
References