I will give my way to you :
My plan is to use KVO to listen the [UIApplication sharedApplication].applicationIconBadgeNumber
- (void)setupBadgeOperation {
[[UIApplication sharedApplication] addObserver:self forKeyPath:@"applicationIconBadgeNumber" options:NSKeyValueObservingOptionNew context:nil];
}
And once value changed, I use [[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil]
to inform the UI where needs to be modified for the change of badge.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"applicationIconBadgeNumber"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil];
}
}
There is three case of receiving a remote notification to change the [UIApplication sharedApplication].applicationIconBadgeNumber
.
a. app is foreground
b. app is background
c. app is not launch
in a and b case, this method will be called:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
void(^tapBlock)(void(^completeHandler)()) = ^(void(^completeHandler)()) {
// here I remove some code not related with the question
NSNumber *badgeNumber = userInfo[@"aps"][@"badge"];
[UIApplication sharedApplication].applicationIconBadgeNumber = badgeNumber.integerValue;
}
in c case, there is no way to get the callback, so I will do it manually.
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:STATUS_BADGENUMBER_CHANGED object:nil];
}
That's all, and works well for me.