iOS 13.1 doesn't receive silent CKQuerySubscription notifications
Asked Answered
T

2

7

My app uses CloudKit Query subscriptions and notifications as part of a CloudKit-based synchronization solution. This works perfectly with iOS 12, macOS 10.14 and even macOS 10.15 beta, but NOT with iOS 13.0, iOS 13.1, iPadOS 13.1 and tvOS 13.0.

Removing and recreating the subscriptions doesn't solve this.

Is this a known problem?

According to the documentation, nothing has changed with CloudKit subscriptions. Or did I miss something?

Tutu answered 25/9, 2019 at 20:35 Comment(11)
I see this on all versions of iOS on and off during development. One day I get notifications and some days I don't. And it's intermittent with difference devices. One day my iPhone gets notifications but my iPad doesn't. Another day it's the opposite. It's frustrating. I can't guess how many hours I've wasted debugging my code thinking it was an issue in my code.Glasgow
BTW - just now I had no problem getting CloudKit notifications on my iPad running 13.1. But a few hours ago it wasn't. Ugh.Glasgow
@Glasgow Thank you for your feedback! Non-working CloudKit notifications in beta releases are pretty standard I thought, so I just expected them to work in the official releases. Unfortunately still no sign of any CloudKit notifications at my side in the latest iOS releases and related OS-es.Tutu
I'm having the same issueReprobate
Added my feedback report, suggest you do the sameReprobate
@theReverend I just filed a report. If it takes too long, I will start a Technical Support Incident.Tutu
Just checked today, no silent notifications on my iPad and iPhone with iOS 13.1Reprobate
@theReverend The iOS 13.1.1 update didn't lead to any improvements. I'm waiting for a response from Apple Developer Technical Support.Tutu
Still happening to me with 13.1.2 very sad, seems like this happens with every iOS update. Last time, it wasn't working while the app was in Guided Access or Single App Mode...Ashmore
Update: the problem seems to be limited to CKQuerySubscription, apps that use CKDatabaseSubscription are not effected. If haven't tested the status of CKRecordZoneNotification's.Tutu
That's odd, so are we supposed to use CKDatabaseSubscription instead? That class doesn't have a way to specify when the subscription fires a notification (e.g. firesOnRecordDelete).Ashmore
T
5

To receive silent CKQuerySubscription notifications in iOS 13.x and tvOS 13.x, the soundName and alertBody parameters of the NotificationInfo of your CKQuerySubscription must not be set.

In the past we have learned to use an empty string for said parameters, to make the whole CloudKit subscription thing working, but that's now history. Apparently Apple has fixed an old bug, causing problems with apps that used this 'workaround'.

I have tested this on iOS 12.4.2, iOS 13.1.2, tvOS 13.0, macOS 10.14.6 and macOS 10.15 GM.

let info = CKSubscription.NotificationInfo()
info.shouldSendContentAvailable = true
// info.soundName = "" // Don't set this property
// info.alertBody = "" // And also leave this this property alone
let subscription = CKQuerySubscription(recordType: "yourRecordType", predicate: NSPredicate(value: true), subscriptionID: "yourSubscription", options: [CKQuerySubscription.Options.firesOnRecordUpdate, CKQuerySubscription.Options.firesOnRecordDeletion])
subscription.notificationInfo = info

// You must first delete the old subscription to change the sound name            
let deleteOperation = CKModifySubscriptionsOperation(subscriptionsToSave: nil, subscriptionIDsToDelete: ["yourSubscription"])      
yourContainer.privateCloudDatabase.add(deleteOperation)

let createOperation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: nil)
createOperation.addDependency(deleteOperation)        
yourContainer.privateCloudDatabase.add(createOperation)
Tutu answered 4/10, 2019 at 19:5 Comment(5)
I haven't used the soundName parameter since iOS 11, and my notifications still don't work. It's possible you fixed it by deleting the existing CKSubscriptions and recreating them. It may not have anything to do with soundName...Ashmore
Another thing I noticed is that the CloudKit Dashboard no longer has a tab/section for subscriptions. I used to be able to see all my subscriptions and edit them in the Dashboard.Ashmore
@Ashmore Have you already tried to recreate your subscriptions? If I recreate the subscriptions with the empty sound name as before, the original problem is back. Subscriptions can be inspected in the CloudKit Dashboard by clicking on the large dropdown that initially shows 'Records' or 'Record Types', depending on the selected main view (Data or Scheme). Take note that you can't edit anything, only delete stuff. Also the sound name property is not shown.Tutu
I haven't tried to recreate the subs. It's possible they'll start working if I do, but I've had to do this before in the past for another CloudKit-related subscription issue. I'm not sure why setting an empty soundName vs. not would create such a problem. It should be easy for Apple to disregard empty soundName parameters. Currently, I set an alertBody = "" (although my Dashboard shows alertBody as a nil parameter), so this issue might appear again for alertBody. I'd much rather Apple just fix these obvious issues (if simply deleting soundName is the solution).Ashmore
Take note that the soundName issue is not detected by me, but by Apple. I have never set an alertBody for query subscriptions, so maybe that's also causing problems in iOS 13, especially if you set it to an empty string. The only necessary parameter setting is shouldSendContentAvailable = true.Tutu
R
4

Silent Notifications stopped working for my app as well in iOS 13.

When I saw Ely's answer, I immediately went to check if I had a soundName set for the notification. Though I did not have any, I saw the alertBody empty string and decided to try it without it. After recreating the subscription, silent notifications started working again in iOS 13. When reading the documentation, it seems obvious that you do not want an alert message on a silent notification. However, I do remember adding it at some point to make it work on another iOS version.

In my case, I was creating a RecordZoneSubscription like this:

CKSubscription * subscription = [[CKRecordZoneSubscription alloc] initWithZoneID:self.dataZone.zoneID subscriptionID:[self mainPrivateSubscriptionID]];

CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.shouldBadge = false;
notificationInfo.alertBody = @""; // THE CULPRIT
notificationInfo.shouldSendContentAvailable = true;
subscription.notificationInfo = notificationInfo;

Solution:

CKSubscription * subscription = [[CKRecordZoneSubscription alloc] initWithZoneID:self.dataZone.zoneID subscriptionID:[self mainPrivateSubscriptionID]];

CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.shouldBadge = false;
notificationInfo.shouldSendContentAvailable = true;
subscription.notificationInfo = notificationInfo;
Reprobate answered 8/10, 2019 at 15:33 Comment(1)
It's really silly. You're right. On a previous version, we needed to add an empty alertBody to make the notifications work, and now we have to delete it. Even worse, in the CloudKit Dashboard, it shows the alertBody field as "nil" even though it's been set as an empty string. Apple could have simply left it that way rather than break it.Ashmore

© 2022 - 2024 — McMap. All rights reserved.