I have the following code running on macOS and iOS:
CKQuerySubscription *zsub = [[CKQuerySubscription alloc] initWithRecordType:ESS_CLOUDCONTROLLER_RECORDTYPE_PUSHNOTE predicate:[NSPredicate predicateWithFormat:@"TRUEPREDICATE"] subscriptionID:@"pushZSub" options:CKQuerySubscriptionOptionsFiresOnRecordUpdate|CKQuerySubscriptionOptionsFiresOnRecordCreation|CKQuerySubscriptionOptionsFiresOnRecordDeletion];
zsub.zoneID = zid;
CKNotificationInfo *inf = [[CKNotificationInfo alloc] init];
inf.shouldSendContentAvailable = YES;
inf.desiredKeys = @[ESS_PN_RECORDFIELD_KEY_OVERALLDATE];
zsub.notificationInfo = inf;
CKModifySubscriptionsOperation *msop = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[zsub] subscriptionIDsToDelete:nil];
msop.qualityOfService = NSQualityOfServiceUserInitiated;
msop.modifySubscriptionsCompletionBlock = ^(NSArray<CKSubscription *> * _Nullable savedSubscriptions, NSArray<CKSubscriptionID> * _Nullable deletedSubscriptionIDs, NSError * _Nullable operationError) {
dispatch_async(dispatch_get_main_queue(), ^{
if (savedSubscriptions.count == 1) { //works also when already created.
compH(YES, nil);
} else {
compH(NO, nil);
}
});
};
[self.database addOperation:msop];
(code synopsis: after i create a custom zone (not shown in code), I add a ckquerysubscription to it for a specific record type, configured as a silent notification)
When I change the according record in my Mac app, I get an immediate silent push on iOS. On macOS, however, after I change the record in my iOS app, I don't get one. Sometimes, one silent push makes it through every now and then a minute+ late or so, and after that, it's going missing again.
What's the deal? Everything's set up correctly (com.apple.developer.aps-environment is set, container-identifiers are the same, icloud services are the same, ubiquity-kvstore-identifier are the same).
I obviously register for remote notifications in both apps. I see all the records and subscriptions and zones in both the Mac and iOS app.
- I tried setting alertBody to an empty string, or soundName to an empty string, or both to an empty string: no difference
- I tried having different subscriptions for my Mac and iOS app, since they use different bundle ids, but that was merged into one subscription server-side, so I'm thinking that's not it
- I tried making it not-silent by setting contentAvailable to NO and adding a full alertBody, title and subtitle. Again, worked on iOS, not on macOS.
This has been going on since macOS 14 Sonoma (when I first got reports of this. Now running on macOS 26.3). Before Sonoma, it worked just fine. Now I thought perhaps it's because I had a subscription on the default zone, and not a custom one, so I tried subscribing to changes on a record in a custom zone (see code above), but that did not change anything either.
It's all working fine, only the push notifications are not making it through to the Mac app.
If I sudo killall apsd (kill the push service daemon), the last push notification suddenly miraculously makes it through, by the way.
At this point, I'm out of ideas and would very much appreciate pointers as to how to debug this. Polling every 30 seconds for changes is so 1990s.
Speaking of which, this is a rather long-time-running app (started in 2011). Could my CloudKit database be “too old” or “corrupted” or whatever?
Thank you kindly,
– Matthias