導讀鏈接:
我們在完善推送功能的時候不光考慮能不能完成功遠程推送,還要注意的是用戶的體驗問題,首先最需要關注的就是應用角標問題。
應用角標
1>何為應用角標
應用角標就是底下截圖這哥們,本初截圖是MAC上截的,手機上也是一樣的效果:
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"http://這就是自定義的設置,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+是不能正常接收到推送的。
以下是設置的截圖:
iOS遠程推送之(一):APNs原理和基本配置
iOS遠程推送之(三):點擊通知橫幅啟動應用
有問題歡迎留言簡書評論,以上!