Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CKModifyBadgeOperation is deprecated in iOS 11. Anyone know an alternative approach?

I have searched, and I cannot find an example. I have also tried adapting this code (recommended elsewhere (CloudKit won't reset my badge count to 0):

func resetBadgeCounter() {
    let badgeResetOperation = CKModifyBadgeOperation(badgeValue: 0)
    badgeResetOperation.modifyBadgeCompletionBlock = { (error) -> Void in
        if error != nil {
            print("Error resetting badge: \(String(describing: error))")
        }
        else {
            UIApplication.shared.applicationIconBadgeNumber = 0
        }
    }
    CKContainer.default().add(badgeResetOperation)
}

This works for now, but is no longer supported, and may go away soon.

I thought perhaps I should use a CKModfyRecordsOperation or some other CKDatabaseOperation, but I can't even guess how.

like image 705
user1739040 Avatar asked Nov 28 '17 22:11

user1739040


1 Answers

I hope this helps someone as there doesn't seem to be another solution/workaround to this.

  1. Create a Notification Service Extension (UNNotificationServiceExtension) for your app. It is fairly straightforward and is described in detail in Modifying Content in Newly Delivered Notifications. You might already have one, if you do any kind of processing on incoming notifications.

  2. Within the extension, you typically do all the processing of the notification in override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void). The request comes with the content of the notification, which includes the badge number. You can then modify that and pass on to the contentHandler to be displayed. (If you are unsure how to do this, check the link above; it has detailed instructions and code.)

  3. To keep track and reset the badge number when needed, you need to take advantage of an app group (e.g. group.com.tzatziki). This way you can share data between the app and the extension. Creating an app group in Xcode can be done by adding the relevant capability and is explained in App Extension Programming Guide: Handling Common Scenarios.

  4. Use a storage mechanism (within the app group) to keep track of the badge count, e.g. UserDefaults, and use it in the extension to update the badge count. In the aforementioned override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void), you could write something like this:

    let badgeNumber = UserDefaults(suiteName: "group.com.tzatziki")?.value(forKey: "badgeNumber") as? NSNumber ?? NSNumber(integerLiteral: 0)
    let badgeNumberInt = badgeNumber.intValue + 1
    notificationContent.badge = NSNumber(value: badgeNumberInt)
    UserDefaults(suiteName: "group.io.prata")?.setValue(notificationContent.badge, forKey: "badgeNumber")
    

where notificationContent is an instance of UNMutableNotificationContent, originating from request.content.mutableCopy() as? UNMutableNotificationContent

  1. Now, the only thing left to do is to reset the badge count in your app, in the shared UserDefaults and in UIApplication.shared.applicationIconBadgeNumber.

Cheers!

like image 168
Nick Toumpelis Avatar answered Nov 10 '22 02:11

Nick Toumpelis