CloudKit won't reset my badge count to 0

2020-02-01 08:20发布

问题:

I've tried a number of things and can't seem to reset the badge count from notifications comings from cloudKit. Has anyone else ran into this problem. Here is what I've tried:

1) Set the badge count locally to 0

  application.applicationIconBadgeNumber = 0; (temporarily removes the badge count).

No luck...

2) Call the server to clear the badge count

 CKModifyBadgeOperation *oper = [[CKModifyBadgeOperation alloc] initWithBadgeValue:0];
  [oper start];

No luck...

3) Pull in all notification changes and mark them all read

NSMutableArray *array = [NSMutableArray array];
CKFetchNotificationChangesOperation *operation = [[CKFetchNotificationChangesOperation alloc] initWithPreviousServerChangeToken:nil];
operation.notificationChangedBlock = ^(CKNotification *notification) {
    [array addObject:notification.notificationID];
};
operation.completionBlock = ^{
        CKMarkNotificationsReadOperation *op = [[CKMarkNotificationsReadOperation alloc] initWithNotificationIDsToMarkRead:array];
        [op start];
};
[operation start];

And again no luck...

Any suggestions would be greatly appreciated! Thanks, Chris

回答1:

You need to do a CKModifyBadgeOperation after processing your notifications.

Here is my Swift function which I call after marking all the notifications as read. I add the operation to the defaultContainer instead of just starting it - I wonder does that make any difference.

func resetBadgeCounter() {
    let badgeResetOperation = CKModifyBadgeOperation(badgeValue: 0)
    badgeResetOperation.modifyBadgeCompletionBlock = { (error) -> Void in
        if error != nil {
            println("Error resetting badge: \(error)")
        }
        else {
            UIApplication.sharedApplication().applicationIconBadgeNumber = 0
        }
    }
    CKContainer.defaultContainer().addOperation(badgeResetOperation)
}


回答2:

The badge and notification operations fail if you don't set a container on it. Since you are not using the completion blocks you are not seeing the error (you are using the default NSOperation completion block which is the wrong one and does not have any error param). Look at the headers for those operations to see the completion block syntax.

And the better way is to add the operation to the container via the addOperation method, this inherently sets the container on the operation before running it. Also it then runs on an internal queue which has the added advantage it prevents running multiple operations concurrently which may lead to conflicts.