I have an iOS app and macOS app that sync data using CloudKit (no CoreData involved). Syncing mostly works, except that on my development machine I don't get any push notifications when other devices make changes.
For example I can make a data change on macOS and it gets pushed to my iOS app immediately, however if I make a change on iOS, the macOS app never gets a notification. I can check in CloudKit dashboard and the data has been updated, and a push was sent, but the macOS app never gets it.
The subscription is set up like so (same code on macOS and iOS) and it reports success on both platforms:
The remote notifications are requested like so, and always reports that is is registered. Though oddly enough I never get the callback to say it has been registered?
And finally, to receive the iCloud change notification:
For example I can make a data change on macOS and it gets pushed to my iOS app immediately, however if I make a change on iOS, the macOS app never gets a notification. I can check in CloudKit dashboard and the data has been updated, and a push was sent, but the macOS app never gets it.
The subscription is set up like so (same code on macOS and iOS) and it reports success on both platforms:
Code Block private func subscribeToCloudKitChanges() { if UserDefaults.standard.bool(forKey: ckSubscriptionStateKey) == true { return } let subscription = CKDatabaseSubscription(subscriptionID: cloudKitPrivateChangeID) let notificationInfo = CKSubscription.NotificationInfo() notificationInfo.shouldSendContentAvailable = true subscription.notificationInfo = notificationInfo let op = CKModifySubscriptionsOperation( subscriptionsToSave: [subscription], subscriptionIDsToDelete: [] ) op.modifySubscriptionsCompletionBlock = { (_, _, error) in if let error = error { logger.error("Error setting up CloudKit subscriptions: \(error.localizedDescription)") UserDefaults.standard.set(false, forKey: ckSubscriptionStateKey) } else { logger.log("CloudKit subscriptions created") UserDefaults.standard.set(true, forKey: ckSubscriptionStateKey) } } op.qualityOfService = .utility ckContainer.privateCloudDatabase.add(op) }
The remote notifications are requested like so, and always reports that is is registered. Though oddly enough I never get the callback to say it has been registered?
Code Block func applicationDidFinishLaunching(_ notification: Notification) { NSApplication.shared.registerForRemoteNotifications() print("Requested remote notifications. Status: \(NSApplication.shared.isRegisteredForRemoteNotifications)") //...
And finally, to receive the iCloud change notification:
Code Block func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) { guard let ckn = CKDatabaseNotification(fromRemoteNotificationDictionary: userInfo) else { return } if ckn.subscriptionID == cloudKitPrivateChangeID { DispatchQueue.main.async { self.cloudKitPrivateDBChanges.send(ckn) } } }