iOS 如何准确显示角标

本地设置角标

iOS 显示角标很容易,在 App 中任意地方调用如下方法都可设置,根据自己的需要设定即可。

// 显示角标,传入待显示角标的数字
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:(int)value];
// 清除角标,传入 0 即可
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; 

不精确显示角标

普通 App 对角标数字要求没那么高,服务端或控制台推送时,总是将推送个数设置为 1,用户点击进入 App 时清除角标。这样简单的做法,能满足大部分 App 的需求。

// 进入 App 时清除角标
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    application.applicationIconBadgeNumber = 0;
}
// 从后台进入前台时清除角标
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    application.applicationIconBadgeNumber = 0;
}

这样做的缺点也很明显,收到多条推送角标数量时角标永远显示 1,用户进入 App 不管是否点击推送的消息,都消除角标。如果要求较高,如何做到精确显示角标呢?

精确显示角标

首先我们要了解一下,手机收到推送消息是如何显示角标数量的。如下所示APNS 按照此格式推送到手机,客户端显示的角标数量为推送的 badge 数值。手机收到推送消息,badge 的值是多少,角标显示的个数就是多少(最大 99999)。

{
    "aps":{
        "alert":"这里是推送显示的消息串",
        "badge":6,
        "sound":"default"
    },
    "custom":"http://www.baidu.com"
}

所以,我们想要精准显示角标数量,必须在客户端读取消息后,客户端上报用户已读消息,将推送消息阅读情况同步到服务器,如极光或者个推。

// 极光和个推同步到服务器的 API 相同,调用可同步到服务器
+ (BOOL)setBadge:(int)value;  // value 取值范围:[0,99999]
+ (void)resetBadge;          // 相当于 [setBadge:0],清空角标

假设服务器推送了 6 条消息,客户点击阅读了 2 条,那我们在设置 App 角标的同时,将未读个数同步到服务器

// 调用系统方法设置 App 显示的角标个数 4
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:4];
// 个推 SDK 同步到服务器
[GeTuiSdk setBadge:4];
// 极光 SDK 同步到服务器
[JPush setBadge:4];

参考文档

极光文档 - 角标控制 个推文档 - 角标控制