Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 13.1 doesn't receive silent CKQuerySubscription notifications

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?

like image 647
Ely Avatar asked Sep 25 '19 20:09

Ely


People also ask

Will IOS awake my app when I receive silent push notification?

Yes. It will. When you click on that. Yeah its ok but being push notification is silent,you are not able to view any alert and cant click.

What is silent push notification in IOS?

Silent push notifications are simply notifications that mobile app users receive without any pings, alerts, or interruptions to the user. They arrive on the mobile device and sit in the notification tray until read or dismissed.


2 Answers

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)
like image 95
Ely Avatar answered Oct 20 '22 06:10

Ely


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

  • On my iOS 12 devices and MacBook, silent notifications kept working correctly.
  • Recreated subscriptions multiple times without success.
  • Checked all steps in https://developer.apple.com/library/archive/qa/qa1917/_index.html

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;
like image 37
the Reverend Avatar answered Oct 20 '22 07:10

the Reverend