在后台运行应用时通过推送通知更新徽章


80

当应用程序进入前台时,我有推送通知正在工作并设法更新图标徽章计数。

但是我对此有点困惑... iPhone收到通知,弹出消息似乎激活了我的应用程序,并且徽章仅在我启动该应用程序后更新。

就用户体验而言,这听起来不对。我的理解是,徽章计数应通过递增计数来通知用户需要采取什么措施,但这不会发生,直到应用程序上线以后。

那么,有没有一种方法可以让应用在收到推送通知时以及在后台时更新其徽章计数?

请注意,我的应用程序不使用位置,并且我已UIRemoteNotificationTypeBadge在通知注册请求中使用。

干杯AF


您想在应用程序图标上显示徽章吗?
阿曼·阿格加瓦尔

我在选项卡上显示计数。并面临同样的问题。当应用程序在后台运行时,计数不会增加。我该如何设定?
Srusti Thakkar '18

Answers:


78

由于推送通知是由iOS处理的,而不是由您的应用程序处理的,因此您无法在收到推送通知时更改应用程序标志。

但是您可以在推送通知的有效负载中发送徽章编号,但是您将必须在计算服务器端进行操作。

您应该阅读《本地和推送通知编程指南》,尤其是《通知有效负载》

有效负载可能如下所示:

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9
    }
}

现在,应用程序应用程序徽章图标将显示9。


4
我已经在这样做了……但是只有当我的应用程序进入前台时才检索该值,以后我会使用[UIApplication sharedApplication]来更新徽章值。applicationIconBadgeNumber= count;
2013年

7
否,您无需在推送通知有效负载中设置徽章编号。
rckoenes 2013年

11
我又看了看我的有效负载结构,似乎我将badge参数的值作为字符串'4'而不是整数4传递了!!!现在我开始工作了……感谢您的帮助
Abolfoooud

我测试了它不工作的时候变化对有效载荷结构徽章
WOD

1
@wod您的意思是:更改有效负载结构标记。
rckoenes

11

当我们处于后台状态时,可以通过在推送通知包中发送“徽章”参数来更改徽章编号。正如@rckoenes指出的那样,JSON徽章的参数必须是INTEGER

相同的示例PHP代码

// Create the payload body
$body['aps'] = array(
        'alert' => $message,
        'badge' => 1,
        'sound' => 'default'
        );

badge => 1 其中1是整数而不是字符串(即不带撇号)


11

实际上,在iOS 10中,远程通知会didReceiveRemoteNotification在您的AppDelegate中自动调用Method。

您有2种在后台更新徽章计数的方法。
我也为当前的应用程序完成了此操作。您也不需要Notification Services扩展。

第一种方式:

将带有有效载荷的APS徽章密钥发送到APN。
这将根据徽章有效载荷中的Integer值更新徽章计数。例如:

// Payload for remote Notification to APN
{
    "aps": {
        "content-available": 1,
        "alert": "Hallo, this is a Test.",
        "badge": 2, // This is your Int which will appear as badge number,
        "sound": default
    }
}

第二种方式:

当applicationState处于时,您可以切换application.applicationState并更新徽章计数.background。但是当发送到APN ex时,您必须注意不要在Notification负载中设置徽章密钥参数

// Payload to APN as silent push notification
{
    "aps": {
        "content-available": 1
    }
}

根据应用程序状态处理徽章更新:

这是我的工作代码,用于在APN的有效负载中在没有徽章密钥的情况下更新徽章计数。

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    print("APN recieved")
    // print(userInfo)
    
    let state = application.applicationState
    switch state {
        
    case .inactive:
        print("Inactive")
        
    case .background:
        print("Background")
        // update badge count here
        application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1
        
    case .active:
        print("Active")

    }
}

重置徽章计数:

当您的应用恢复为活动状态时,请不要忘记重置您的徽章计数。

func applicationDidBecomeActive(_ application: UIApplication) {
    // reset badge count
    application.applicationIconBadgeNumber = 0
}

如果应用未在后台运行,如何更新徽章?
Nagendra Rao

1
如果您发送具有内容可用密钥的APS,则无论应用程序的状态如何,它将运行didReceiveRemoteNotification方法。只需在本机设备上试用即可。如果您在iOS上,则可以使用此工具将JSON对象发送到APN:github.com/noodlewerk/NWPusher
Gkiokan

哇,太好了,如果我发送的通知没有内容怎么办?(关于任何非后台通知)。didReceiveRemoteNotification不被称为
StackExploded

6
    **This is the APNS payload get back from server.**

    {
        "aps" : {
            "alert" : "You got your emails.",
            "badge" : 9,
            "sound" : "bingbong.aiff"
        },
        "acme1" : "bar",
        "acme2" : 42
    }

密钥徽章的值将自动视为徽章计数。在ios应用程序端,无需计算或处理计数。在上面的示例中9是徽章计数,因此您的应用程序图标将显示9。

注意当您的应用关闭时,您无法独自处理徽章。这就是为什么我们使用APNS Payload的徽章密钥有关通知的更多说明,请参阅文档

如果您想自己减少徽章数量,请减少数量并自己更新。


4

如果使用NotificationServiceExtension,则可以在其中更新徽章。

var bestAttemptContent : UNMutableNotificationContent? // 
bestAttemptContent.badge = 0//any no you wanna display

每次您的应用程序收到通知时,都会调用您的服务扩展。将该值保存为用户默认值并显示。要在应用程序和扩展名之间共享用户默认设置,您需要在应用程序中启用应用程序组。 在这里阅读更多


您可以将该通知计数保存在服务器上,并随通知一起发送。
Surjeet Rajput,

我使用Firebase Cloud Messaging,您知道该怎么做吗?
Ghiggz Pikkoro


1

对于Firebase Cloud Messaging(FCM),应如下所示:

{
  "to": "some_token",

  "notification": {
    "body": "this is a body",
    "title": "this is a title",
    "badge" : 1
  }, 

  "priority": "high", 
}

0
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    application.applicationIconBadgeNumber = 0;
    NSLog(@"userInfo %@",userInfo);

    for (id key in userInfo) {
        NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
    }

    [application setApplicationIconBadgeNumber:[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]];
    NSLog(@"Badge %d",[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]);
}

为什么使用intValue而不是NSInteger的integerValue?@property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
Alex Zavatone 2015年

0

正如@rckoenes所说,您将必须在计算服务器端进行操作,但是您怎么知道何时增加应该在有效载荷中发送的徽章编号值呢?

将在您启动应用程序时向您的服务器发送一条消息,指示该应用程序已启动。因此,在服务器端,您再次从badge = 0开始,并且当服务器未收到任何消息时,每个推送通知有效负载都会增加badge的数量。


0

在APNS有效负载中必须定义“内容可用”:1,以便在后台模式下更新徽章计数

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {


// increase badge count, but no need if you include content-available

application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1

}

func applicationDidBecomeActive(_ application: UIApplication) {

// reset badge count

application.applicationIconBadgeNumber = 0

}

例如

"aps":{
    "alert":"Test",
    "sound":"default",
    "content-available":1

}

content-available = 1的目的是不向徽章发出静默通知。
Manish


-1

在打开应用程序后收到远程通知后,

didBecomeActive您的方法中获取当前的徽章编号AppDelegate

使用以下代码文件:

int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badgeCount = badgeCount + 1;

3
直到用户点击应用程序或启动应用程序的通知,该功能才起作用。当应用程序处于后台并且用户与应用程序或通知进行交互之前,它将不会执行OP想要的更新徽章的操作。
Alex Zavatone 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.