There isn't a signing capability for icloud that is available for either the app or watchos extension targets.
My end goal is to have the CoreData CloudKit container that is used by both applications to be in sync and fetch / update the models they modify.
Here is what I've done so far:
4. Add the persistence context to the watch app
5. Define the PersistenceStore
6. Go to my data model DataModel.xcdatamodeld and go to Configurations -> Default and ticked the box "Used with cloudkit"
7. I run both the ios app and watch app in simulators but do not see any cloudkit containers created at:
https://icloud.developer.apple.com/dashboard/#home
What am i missing?
My end goal is to have the CoreData CloudKit container that is used by both applications to be in sync and fetch / update the models they modify.
Here is what I've done so far:
Create iOS with watch app cookie cutter app with xcode 12
Add "Remote Notification" for Background Modes for both the iOS and watch extension targets. Note I CANNOT find anything to do with icloud or cloudkit as a capability to add.
Add the persistence context to the iOS App
Code Block swift @main struct MyApp: App { @Environment(\.scenePhase) private var scenePhase @StateObject private var persistentStore = PersistentStore.shared var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, persistentStore.context) }.onChange(of: scenePhase) { phase in switch phase { case .active: print("active") case .inactive: print("inactive") case .background: print("background") persistentStore.save() @unknown default: print("default") } } } }
4. Add the persistence context to the watch app
Code Block swift import SwiftUI import CoreData @main struct MyApp: App { let context = PersistentStore.shared.context var workoutManager = WorkoutManager() @SceneBuilder var body: some Scene { WindowGroup { NavigationView { ContentView() .environment(\.managedObjectContext, context) .environmentObject(workoutManager) } } WKNotificationScene(controller: NotificationController.self, category: "myCategory") } }
5. Define the PersistenceStore
Code Block swift import Foundation import CoreData public class PersistentStore: ObservableObject { var context: NSManagedObjectContext { persistentContainer.viewContext } // One line singleton static let shared = PersistentStore() // Mark the class private so that it is only accessible through the singleton `shared` static property private init() {} private let persistentStoreName: String = "DataModel" // MARK: - Core Data stack lazy var persistentContainer: NSPersistentContainer = { // let container = NSPersistentContainer(name: persistentStoreName) // OR - Include the following line for use with CloudKit - NSPersistentCloudKitContainer let container = NSPersistentCloudKitContainer(name: persistentStoreName) let cloudStoreDescription = NSPersistentStoreDescription() cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "com.rbl.mnodel") // Update the container's list of store descriptions container.persistentStoreDescriptions = [ cloudStoreDescription ] // Enable remote notifications guard let description = container.persistentStoreDescriptions.first else { fatalError("###\(#function): Failed to retrieve a persistent store description.") } description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) // load both stores container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error { // Replace this implementation with code to handle the error appropriately. fatalError("Unresolved error \(error)") } }) // Include the following line for use with CloudKit - NSPersistentCloudKitContainer container.viewContext.automaticallyMergesChangesFromParent = true // Include the following line for use with CloudKit and to set your merge policy, for example... container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy // Observe Core Data remote change notifications. NotificationCenter.default.addObserver( self, selector: #selector(self.changes), name: .NSPersistentStoreRemoteChange, object: nil) return container }() @objc func changes () { print("Changes received from cloudkit") } // MARK: - Core Data Saving and "other future" support (such as undo) func save() { let context = persistentContainer.viewContext if context.hasChanges { NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") } if context.hasChanges { do { try context.save() } catch { // Customize this code block to include application-specific recovery steps. let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } } }
6. Go to my data model DataModel.xcdatamodeld and go to Configurations -> Default and ticked the box "Used with cloudkit"
7. I run both the ios app and watch app in simulators but do not see any cloudkit containers created at:
https://icloud.developer.apple.com/dashboard/#home
What am i missing?
For people trying to find the answer to this like I struggled to find, I had an old xcode team signing. The team you select when you create your project determines the features / capabilities you can add to your app. Go create a new provisioning in your developer dashboard & assign the capabilities you want in your app to that app provisioning.