iOS遠(yuǎn)程推送主要流程為:注冊(cè)推送的token肴甸,把token上傳到服務(wù)器->接收到服務(wù)器的推送->處理推送。
注冊(cè)token時(shí)囚巴,需要用戶同意授權(quán)進(jìn)行推送原在,否則不能獲取token,則推送功能無(wú)法實(shí)現(xiàn)彤叉。
遠(yuǎn)程推送的框架在iOS10之后有更新庶柿,因此如果要兼容iOS10之前的系統(tǒng),則需要進(jìn)行判斷系統(tǒng)版本秽浇。
1浮庐、注冊(cè)推送的token并上傳
首先打開(kāi)項(xiàng)目的推送功能,如下圖:
然后實(shí)現(xiàn)注冊(cè)token的方法柬焕,代碼如下:
//iOS10之后需要引入新框架
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
- (void)replyPushNotificationAuthorization:(UIApplication *)application{
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
//iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//必須寫代理审残,不然無(wú)法監(jiān)聽(tīng)通知的接收與點(diǎn)擊事件
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
//用戶點(diǎn)擊允許
NSLog(@"PushNotification====注冊(cè)成功");
}else{
//用戶點(diǎn)擊不允許
NSLog(@"PushNotification====注冊(cè)失敗");
}
}];
//獲取通知注冊(cè)狀態(tài)
// [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
// NSLog(@"PushNotification====%@",settings);
// }];
}else if ([[UIDevice currentDevice].systemVersion floatValue] >8.0){
//iOS 8 - iOS 9系統(tǒng)
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
}
//注冊(cè)遠(yuǎn)端消息通知獲取device token
[application registerForRemoteNotifications];
}
我們?nèi)缓笤贏ppDelegate里面實(shí)現(xiàn)兩個(gè)代理方法,在第一次申請(qǐng)token時(shí)斑举,需要取得用戶的同意搅轿,會(huì)彈出推送權(quán)限申請(qǐng)對(duì)話框,當(dāng)用戶同意后會(huì)調(diào)用token申請(qǐng)成功的代理方法富玷,當(dāng)用戶拒絕后會(huì)調(diào)用token申請(qǐng)失敗的方法璧坟。代碼如下:
#pragma mark - 授權(quán)申請(qǐng)token回調(diào)
//token獲取成功
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSData *apnsToken = [NSData dataWithData:deviceToken];
NSString *tokenString = [self getHexStringForData:apnsToken];
NSLog(@"My token = %@", tokenString);
}
- (NSString *)getHexStringForData:(NSData *)data {
NSUInteger length = [data length];
char *chars = (char *)[data bytes];
NSMutableString *hexString = [[NSMutableString alloc] init];
for (NSUInteger i = 0; i < length; i++) {
[hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]];
}
return hexString;
}
//token獲取失敗
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
當(dāng)我們token獲取成功后没宾,把token上傳到服務(wù)器,服務(wù)器即可根據(jù)token及相關(guān)參數(shù)可以進(jìn)行推送沸柔。上傳根據(jù)自己的后臺(tái)服務(wù)器接口進(jìn)行上傳即可。
2铲敛、接收到推送及處理
接收到推送時(shí)的情況有幾種褐澎,如下:
APP在沒(méi)有啟動(dòng)及在后臺(tái)的情況下收到推送,此時(shí)會(huì)在通知欄進(jìn)行顯示伐蒋;
APP在前臺(tái)收到推送工三,此時(shí)會(huì)調(diào)用收到推送的方法,是否顯示由代碼決定先鱼。
當(dāng)用戶點(diǎn)擊推送時(shí)俭正,我們也需要進(jìn)行處理,此時(shí)調(diào)用的代理方法也有區(qū)別焙畔,處理推送的流程如下圖(對(duì)應(yīng)推送的處理掸读,我們也需要區(qū)分iOS10及iOS10之前的系統(tǒng)):
我們?cè)贏ppDelegate實(shí)現(xiàn)相關(guān)代理方法,即可處理相應(yīng)的推送宏多,代碼如下:
#pragma mark - function 1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self replyPushNotificationAuthorization:application];
NSLog(@"launchOptions == %@",launchOptions);
return YES;
}
#pragma mark - function 2 iOS 10之前以前的用戶
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"push notification did receive remote notification:%@", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
#pragma mark - function 3 iOS10及以后的用戶
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSLog(@"push notification did receive remote notification:%@",notification.request.content.userInfo);
// 需要執(zhí)行這個(gè)方法儿惫,選擇是否提醒用戶,有Badge伸但、Sound肾请、Alert三種類型可以設(shè)置,決定是否再顯示此通知來(lái)提醒用戶
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
}
#pragma mark - function 4 iOS10及以后的用戶
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
NSLog(@"push notification did receive remote notification:%@",response.notification.request.content.userInfo);
completionHandler();
}
對(duì)于接收到的推送處理完畢后,一個(gè)推送就形成了閉合更胖,完成了它的使命铛铁。
Demo地址:https://github.com/XMSECODE/ESCPushNotificationDemo