Search code examples
iosswiftswiftuiapple-watchcloudkit

Knowing when the watch app receives a push notification from Cloudkit


I have an app that has an Apple Watch extension.

Both use Core Data.

I have enabled, on both, the CloudKit ability.

I have configured both apps as described here

I open the iOS app, change the database, but nothing happens on the watch. I mean, the results are not updated on the watch.

Two questions:

  1. Do I have to do something to push or to receive the notification from iCloud?
  2. How do I know when the watch receives some notification from iCloud? Is that a way to debug this?

Solution

  • I have configured both my iOS and Watch apps following 100% of what Apple wrote on the document I mention on the question, and the apps were not synching over CloudKit.

    The solution was to modify PersistenceController to this:

    import CoreData
    
    struct PersistenceController {
      static let shared = PersistenceController()
      let container: NSPersistentCloudKitContainer
      
      var context: NSManagedObjectContext {
        return container.viewContext
      }
      
      init(inMemory: Bool = false) {
        container = NSPersistentCloudKitContainer(name: "MyApp")
        container.viewContext.automaticallyMergesChangesFromParent = true
        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    
        guard let description = container.persistentStoreDescriptions.first else{
          fatalError("###\(#function): Failed to retrieve a persistent store description.")
        }
        
        description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
        
        // Generate NOTIFICATIONS on remote changes
        description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
        description.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.myCompany.MyApp")
    
        
        if inMemory {
          container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
    
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
          if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
          }
        })
      }
    }
    

    Then remove the apps from your iPhone and Watch and run again. It will work instantly.