当应用程序在后台运行时收到通知时,我使用以下代码在应用程序图标上设置徽章。也就是说,当应用程序最小化时收到通知时,我的代码/日志永远不会被触发(请参阅日志:"NSLog应用程序处于后台"),我不知道为什么?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[NSNotificationCenter defaultCenter] postNotificationName:@"pushNotification" object:nil userInfo:userInfo];
NSLog(@"application Active - notication has arrived while app was opened");
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"Notification received when open");
if(application.applicationState == UIApplicationStateInactive) {
NSLog(@"Inactive - the user has tapped in the notification when app was closed or in background");
completionHandler(UIBackgroundFetchResultNewData);
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UITabBarController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"tabBarController"]; // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
[viewController setSelectedIndex:0];
;
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotificationReceived" object:nil];
}
if (application.applicationState == UIApplicationStateBackground) {
NSLog(@"APP WAS IN BACKGROUND");
static int i=1;
[UIApplication sharedApplication].applicationIconBadgeNumber = i++;
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application{
static int i=0;
[UIApplication sharedApplication].applicationIconBadgeNumber = i;
NSLog(@"Triggered!");
}
这是远程通知的正确行为。
当您的应用程序处于后台时,您的应用将不会接收didReceiveRemoteNotification
调用,除非用户点击通知警报。
以下是它的工作原理。
1) 当您的应用程序处于后台(或已挂起)并且收到远程通知时,将显示iOS系统警报。
2) 如果用户通过点击通知警报打开你的应用程序,那么你的应用将移动前台,并调用didReceiveRemoteNotification
。
3) 如果用户忽略通知或取消通知,则您的应用程序将保留在后台,并且不会调用didReceiveRemoteNotification
。
也就是说,不需要在代码中设置应用程序徽章。您的推送通知负载可以包括一个密钥,iOS在系统收到您的通知时使用该密钥来设置应用程序徽章。
您只需在通知的有效载荷中包含密钥badge
:
{
"aps" : {
"alert" : {
"title" : "Notification title",
"body" : "Notification body"
},
"badge" : 5
}
}
我建议你看看苹果公司关于创建远程通知有效负载的文档,其中解释了所有选项:
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc
话虽如此,可以确保iOS在应用程序处于后台时调用didReceiveRemoteNotification
。
为了实现这一点,您需要在负载中设置content-available
参数,并发送一个"静默"通知。静默通知意味着用户永远不会看到警报,但您的应用程序将在有限的时间内静默显示在前台,并调用didReceiveRemoteNotification
。
不过,对于您的场景来说,这不是一个合适的选择。它旨在更新应用程序的内容,而不仅仅是更新徽章。
然而,如果你对静默通知感兴趣,你可以在这里看到文档:
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_updates_to_your_app_silently?language=objc
[UIApplication sharedApplication].applicationIconBadgeNumber = 3;