Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CloudKit CKSubscription without notifications?

I'm writing a Swift app with CloudKit. When a record is modified in CloudKit by a device, I want the corresponding records to be updated in the local storage of the other devices without displaying a push notification.

Do I need to call registerUserNotificationSettings in didFinishLaunchingWithOptions (meaning that the user has to accept the notifications for my app) even if I don't plan to display any push notification?

application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert, categories: nil))
like image 538
franswa Avatar asked Nov 26 '15 09:11

franswa


People also ask

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.

Are Apple push notifications guaranteed?

The system makes every attempt to deliver local and remote notifications in a timely manner, but delivery isn't guaranteed. The PushKit framework offers a more timely delivery mechanism for specific types of notifications, such as those VoIP and watchOS complications use.

How do push notifications work?

Push notifications look like SMS text messages and mobile alerts, but they only reach users who have installed your app. All the mobile platforms – iOS, Android, Fire OS, Windows and BlackBerry – have their own services for supporting push.


2 Answers

Yes you do need to call registerUserNotificationSettings even all you need is background remote notification. So user will be prompt for notifications permission. It makes no sense as users will not be seeing the notifications but that's how it is.

I use this to set it up:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let settings = UIUserNotificationSettings(forTypes: .None , categories: nil) application.registerUserNotificationSettings(settings) application.registerForRemoteNotifications() }

Make sure when you call CloudKit saveSubscription you provide shouldSendContentAvailable = true. The following code is for subscription for a custom zone:

let subscription = CKSubscription(zoneID:zoneID, options: CKSubscriptionOptions(rawValue: 0))

let notificationInfo = CKNotificationInfo()
notificationInfo.shouldSendContentAvailable = true

subscription.notificationInfo = notificationInfo

CKContainer.defaultContainer().privateCloudDatabase.saveSubscription(subscription) { subscription, error in
}

You also need to enable Background Modes capability under Xcode for your project, and tick the box Remote Notifications.

User can go to Settings app to disable notifications for your app. But you will still receive remote notification trigger by CloudKit server.

Implement the following functions in your AppDelegate to receive remote notifications:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {}
like image 50
Jaxon Du Avatar answered Oct 13 '22 10:10

Jaxon Du


In this case you do not need to call registerUserNotificationSettings.

You need to add the Info.plist setting "Required background mode" (UIBackgroundModes), "App downloads content in response to push notifications" (remote-notification). And also call registerForRemoteNotifications. Finally, set notificationInfo.shouldSendContentAvailable = YES; on your subscription.

Now since your app is being run to respond to all notifications you need to be careful to handle the case where a notification is missed, you can use airplane mode to test that, only the last is delivered.

Note, once you have created your subscription from any device, application:didReceiveRemoteNotification:fetchCompletionHandler: will be called on all devices that are using the same iCloud account and have the app installed.

like image 30
malhal Avatar answered Oct 13 '22 10:10

malhal