iOS远程推送之(二):角标applicationIconNumber设置

导读链接:

iOS远程推送之(一):APNs原理和基本配置

我们在完善推送功能的时候不光考虑能不能完成功远程推送,还要注意的是用户的体验问题,首先最需要关注的就是应用角标问题。

应用角标

1>何为应用角标
应用角标就是底下截图这哥们,本初截图是MAC上截的,手机上也是一样的效果:

Snip20170627_36.png

2>应用角标原理
应用角标其实是由系统设置的,APNs将推送的消息传送到系统的时候根据上面的消息payload内容中的badge数值来给应用的图标赋值,这样应用的HomeScreen上显示的图标右上角就会出现相应的数字,不管你应用启动没启动都会显示相应的数字。所以如果是我们自己后台来实现这个推送功能的话,那么就需要一套角标逻辑来完善用户体验了。
推送消息的标准格式如下:

{"aps":
    {"alert":"I'm a very handsome boy! Nice IT guys!",
     "badge":6,
     "sound": "default"
    }
}

自定义推送消息的格式如下:

{"aps":
    {"alert":"I'm a very handsome boy! Nice IT guys!",
     "badge":6,
     "sound": "default"
    },
 "custom":"http://www.baidu.com"//这就是自定义的设置,key也可以改
}

3>应用角标设置
那么既然能显示,那么也应该要能消除吧,或者说可以设置这个值,要不然用户进去应用了或者查看了相关功能之后你的角标数按道理就应该减少,所以这就涉及到了角标的设置了。
那么角标是属于UIApplication的一个NSInteger属性,如下:

// set to 0 to hide. default is 0. In iOS 8.0 and later, your application must register for user notifications using -[UIApplication registerUserNotificationSettings:] before being able to set the icon badge.
@property(nonatomic) NSInteger applicationIconBadgeNumber;  

意思是说:当这个角标的值为0就是隐藏角标,默认是隐藏的;并且在iOS8之后你如果要设置角标就需要通过-[UIApplication registerUserNotificationSettings:]此方式注册通知

设置角标的代码:

[UIApplication sharedApplication].applicationIconBadgeNumber = 5;

4>应用角标处理
我只是简单的把所有的图标改成0隐藏,如果需要更细节处理自己思考下或者给我简书留言,处理代码如下:

if (application.applicationIconBadgeNumber > 0) {  
        application.applicationIconBadgeNumber = 0; 
}

应用角标处理逻辑有以下几种情况:
①当我们用户处于前台的时候,通知横幅不会弹出,但是依然会调用以下的方法:

//iOS6及以下(前台是直接走这个方法不会出现提示的,后台是需要点击相应的通知才会走这个方法的)
- (void)DSPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    //handle code here...
}

//iOS7及以上
- (void)DSPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //handle code here...
}

那么我们就需要在这个里面相应的把代码角标设置为0,因为你已经在前台了所以不需要出现角标,表明告诉用户没有新的内容,而且也要说一个问题就是某些童鞋说在某一个界面里面的消息通知该怎么办?那我只能说这个凉拌!当然是根据业务需求来办咯,我没法给出更多实际的代码,因为没法给。

②当我们的应用处于后台的时候,接收到了通知,我们是通过点击应用图标的方式来激活应用程序的,那么这个时候也应该要做下处理,在以下代理方法里面添加处理代码:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{
   //handle code here...
}

③当我们应用处于未启动状态时,接受到了通知但是是通过点击应用图标来启动应用程序的话,那么此种情况的处理同第②种情况处理,因为也会调用applicationDidBecomeActive:这个代理方法

④当我们应用程序处于后台时,此时接收到通知之后,点击了横幅进入的应用,那么此时的做法同①,具体是接着会进入哪个界面那么根据推送来的消息里面的自定义字段我们来跳转不同的界面的需求,顺带加上角标处理代码即可。
PS: 如何处理自定义字段,请参考iOS之远程推送APNs中的DSPushService类中对应处的处理,这里还是贴上吧,代码如下:

#pragma mark - 收到远程推送通知的相关方法
//iOS6及以下(前台是直接走这个方法不会出现提示的,后台是需要点击相应的通知才会走这个方法的)
- (void)DSPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [self DSPushApplication:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:nil];
}

//iOS7及以上
- (void)DSPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"%@", userInfo);
   
    
    //注意HomeScreen上一经弹出推送系统就会给App的applicationIconBadgeNumber设为对应值
    if (application.applicationIconBadgeNumber > 0) {
        application.applicationIconBadgeNumber = 0;
    }
    
   
    
    NSLog(@"remote notification: %@",[userInfo description]);
    NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];
    
    NSString *alert = [apsInfo objectForKey:@"alert"];
    NSLog(@"Received Push Alert: %@", alert);
    NSString *sound = [apsInfo objectForKey:@"sound"];
    NSLog(@"Received Push Sound: %@", sound);
    NSString *badge = [apsInfo objectForKey:@"badge"];
    NSLog(@"Received Push Badge: %@", badge);
    
    //这是播放音效
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    
    //处理customInfo
    if ([userInfo objectForKey:@"custom"] != nil) {
        //custom handle code here...
    }
    completionHandler(UIBackgroundFetchResultNoData);
}

⑤当我们的应用程序处于未启动状态,然后接收到通知,点击通知横幅进入应用,此时按照以下做处理:

- (BOOL)Application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //当应用程序未启动的时候,点击横幅来启动应用可以做如下处理
    NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
    if (userInfo != nil) {
        //如果有值,说明是通过远程推送来启动的
        //code here...
    }
    return YES;
}

5>角标相关问题
①问题一:
Q:如何做到角标的逐步增加,比如说用户一直没有打开相应的应用,但是呢需要角标相应的增加,比如说QQ、微信等此类应用是需要和会话内容一致的,那么这个怎么做呢?
A:这个是需要后台服务器来支持的,因为只要系统接收到这个通知之后就会根据里面的消息内容的badge值设置为角标值,那这样的话也就只能是服务器来控制器了,也就是把这个角标加值逻辑交给后台了。当然也不只是后台的事儿,因为有时候我们处理角标的时候不会一进入到应用就把角标值设置为0,而是进入到某一个界面或者点击了某一个页面或者按钮这样就把相应的角标数给减少掉,那么我们在点击完相应界面后就应该发送一个角标处理请求给后台告诉后台要减少多少角标数,这样就能够做到下次服务器发送通知的时候对应上了。
②问题二:
Q:我有一位朋友问过我一个奇葩的需求就是他们的产品要求他们把角标数统一改成99+这种情况,然后他跟我说别的APP实现了,问我怎么修改?
A:我是这么回答的。首先这么考虑这个问题,暂时先不考虑能不能改的问题,如果能用代码改也是没用的,如果不能用代码改那么要改也是在系统设置那儿改,据我所知设置是没有相应的改动的位置的。那么说说代码改动为什么不行呢,当我们的程序处于后台或者压根没有启动的时候,这个时候通知照样要接收,而且要递增,你程序内部的代码根本不起作用,所以这个只能是根据系统的不同版本来定的。据我所知,目前的版本都是数字没有限制,但是呢如果超过999999,会将中间的数字以...处理,如果要实现99或者999这种效果,只能是服务器那边设定推送消息中badge字段设置为99或者999即可。我试过了直接将badge设置为99+是不能正常接收到推送的。
以下是设置的截图:

1.jpg
2.jpg
4.jpg
5.jpg
6.jpg
7.jpg

iOS远程推送之(一):APNs原理和基本配置
iOS远程推送之(三):点击通知横幅启动应用

有问题欢迎留言简书评论,以上!

逗比.gif

推荐阅读更多精彩内容

  • 极光推送: 1.JPush当前版本是1.8.2,其SDK的开发除了正常的功能完善和扩展外也紧随苹果官方的步伐,SD...
    Isspace阅读 5,499评论 10 16
  • WWDC session - Notifications 学习总结,如有不妥之处,望请指正🙏🙏 pusher工具[...
    kurt_wang阅读 4,159评论 12 28
  • 前言 本文是一篇转载文章,在这一篇实用的文章里,你可以按照上面的步骤实现不借助第三方和服务器端,自己给自己的设备发...
    進无尽阅读 960评论 6 6
  • 携友驱车向金阳,快步甩手在湖旁。 微风拂面皱湖水,柳摇花笑在两旁。 绿丝带上万步走,相谈甚欢聊健康。 吾从健康自由...
    书山路上阅读 116评论 0 0
  • 管仲夷吾者,颍上人也。少时常与鲍叔牙游,鲍叔知其贤。管仲贫困,常欺鲍叔,鲍叔终善遇之,不以为言。已而鲍叔事齐公子小...
    熹嘻阅读 132评论 0 1