94

当应用程序被带到前台时,我已经让推送通知工作并设法更新图标徽章计数。

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

就用户体验而言,这听起来并不正确。我的理解是,徽章计数应该通过增加计数来通知用户需要采取的行动,但这要等到应用程序上线后才会发生。

那么有没有办法告诉应用程序在收到推送通知时以及在后台时更新其徽章计数?

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

4

12 回答 12

92

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

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

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

有效载荷可能如下所示:

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

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

于 2013-01-10T11:25:41.020 回答
19

实际上,在 iOS 10 中,远程通知会自动调用didReceiveRemoteNotificationAppDelegate 中的方法。

您有 2 种方法可以在后台更新徽章计数。
我也为我当前的应用程序做了这个。您也不需要通知服务扩展。

第一种方式:

将带有有效负载的 APS 徽章密钥发送到 APN。
这将根据您的徽章有效负载中的整数值更新徽章计数。前任:

// 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
    }
}

第二种方式:

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

// 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
}
于 2018-11-05T17:58:43.730 回答
11

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

执行相同操作的示例 PHP 代码

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

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

于 2013-05-09T07:26:11.713 回答
7
    **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 中的徽章密钥的原因 有关通知的更好说明,请参阅文档

如果您想自己减少徽章计数。减少计数并自行更新。如下

于 2017-04-19T14:16:26.153 回答
6

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

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

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

于 2017-11-08T08:10:28.723 回答
3

对于 Firebase 云消息传递 (FCM),它应该是这样的:

{
  "to": "some_token",

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

  "priority": "high", 
}
于 2019-10-24T14:05:45.640 回答
3

从 iOS 10 开始,您可以为您的应用开发通知服务扩展。当您收到通知时,系统将启动它,您可以计算徽章的有效编号并设置它。

看看文档: https ://developer.apple.com/documentation/usernotifications/unnotificationserviceextension

于 2017-11-21T08:30:29.260 回答
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]);
}
于 2013-01-10T11:31:46.517 回答
0

在 apns 有效负载中必须定义 "content-available":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

}
于 2018-12-01T09:49:39.133 回答
0

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

当您启动应用程序时,会向您的服务器发送一条消息,指示应用程序已启动。因此,在服务器端,您从徽章 = 0 重新开始,虽然服务器没有收到任何消息,但随着每个推送通知有效负载增加徽章编号。

于 2016-02-16T08:46:25.173 回答
0

在遗产其工作中,“徽章”设置计数

{
  "to": "token",
  "notification": {
    "title": "Example",
    "body": "Tiene 22 actualizaciones.",
    "badge":278
  },
  "data": {
    "story_id": "story_12345",
    "count_vaca":22
  }
}
于 2019-11-05T06:19:10.507 回答
-2

打开App收到远程通知后,

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

使用以下代码文件:

int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badgeCount = badgeCount + 1;
于 2014-11-18T13:32:52.877 回答