Not getting CloudKit silent push notifications on macOS

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:
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)
        }
   }
}


Post not yet marked as solved Up vote post of fractal Down vote post of fractal
1.7k views

Replies

So I read through TN2265: Troubleshooting Push Notifications and it looks like the problem is that APSD never connects to the *development* iCloud environment on macOS because:
  • I get neither the success nor the failure delegate callback when registering for remote notifications

  • apsctl status shows:

Code Block
daemon status: Running
certificate status: Provisioned, using existing certificate
app refresh activity: Yes
connection environment: development
courier status: Not connected because there are no eligible topics
enabled: Yes
stream connected: No
connected to service: No


I'm guessing "there are no eligible topics" means "you are not running any apps that connect to the development environment", so perhaps the problem is that it's not noticing that I'm launching my app that wants the dev environment? I'm kinda stuck at this point though because I don't see any documentation on apsctl that would allow me to troubleshoot further.
Filed FB8968738, I'll post here again if anything comes of it.
This is exactly the same issue as I have. I believe the issue started with either one of the Xcode 12.x releases or after upgrading to Big Sur.