iOS—iOS10适配iOS当前所有系统的远程推送
一、iOS推送通知简介
众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出现的Category(分类, 也可称之为快捷回复), iOS9出现的Text Input action(文本框快捷回复).
而在iOS10, 苹果可谓是大刀阔斧般的, 对远程通知和本地通知进行了大范围的更新. iOS10推出了全新的UserNotifications框架(iOS10之前从属于UIKit框架).
新的推送通知框架, 整合了本地推送和远程推送的点击处理方法, 使得以前专门处理推送点击的方法只能处理静默推送了.
二、远程推送通知介绍
1、什么是远程推送
在联网的情况下,由远程服务器推送给客户端的通知,又称APNs(Apple Push Notification Services)不管应用是打开还是关闭的情况下,都能接收到服务器推送的远程通知在联网状态下,所有苹果设备都会与苹果服务器建立长连接
2、远程推送的实现原理:
1.打开App时: 发送UDID
和BundleID
给APNs
加密后返回deviceToken
2.获取Token
后,App调用接口,将用户身份信息和deviceToken
发给服务器,服务器记录
3.当推送消息时, 服务器按照用户身份信息找到存储的deviceToken
,将消息和deviToken
发送给APNs
4.苹果的APNs通过deviceToken
, 找到指定设备的指定程序, 并将消息推送给用户
3、实现远程推送功能的前提
1.真机
2.调试阶段的证书
iOS_development.cer
用于真机调试的证书
aps_development.cer
用于真机推送调试能的证书
xxx.mobileprovision
描述文件,记录了能够调试的手机、电脑和程序
3.发布阶段的证书
iOS_distribution.cer
用于发布app的证书
aps.cer
用于发布时,让app有推送功能的证书
xxx.mobileprovision
描述文件,记录了能够发布app的电脑
如何配置证书,请参考我的另一博文: iOS-推送,证书申请,本地推送
二、 iOS10远程推送通知的处理方法
当点击了推送后, 如果你希望进行处理. 那么在iOS10中, 还需要设置UNUserNotificationCenter
的delegate
, 并遵守UNUserNotificationCenterDelegate
协议.
以及实现下面实现3个方法, 用于处理点击通知时的不同情况的处理
willPresentNotification:withCompletionHandler
用于前台运行
didReceiveNotificationResponse:withCompletionHandler
用于后台及程序退出
didReceiveRemoteNotification:fetchCompletionHandler
用于静默推送
1.前台运行 会调用的方法
前台运行: 指的是程序正在运行中, 用户能看见程序的界面.
iOS10会出现通知横幅, 而在以前的框架中, 前台运行时, 不会出现通知的横幅.
代码开始前的设置
iOS 10 的推送 与原来的都不一样,他把本地的推送 跟 远程的推送结合到一起了,UserNotifications.framework 库。在使用推送的时候,先开启通知的开关。
就是上面这个。当你开启后,xcode 会自动帮你在 项目里面创建一个文件,xxxx.entitlements.
这个文件是系统帮你创建的,不用管它。
在appDeletgate 文件里面需要先导入 UNUserNotificationCenterDelegate 这个代理。他的代理方法分别是
- – (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
- – (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0)
代码如下:
<em> 2<br/> 3 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {<br/> 4<br/> 5<br/> 6<br/> 7 /**<br/> 8<br/> 9 注册远程推送和本地通知,适配至最新系统,目前是 iOS10<br/> 10<br/> 11 */<br/> 12<br/> 13 [self registerRemoteNotificationsForAlliOSSystemVersion];<br/> 14<br/> 15<br/> 16<br/> 17<br/> 18<br/> 19 // Override point for customization after application launch.<br/> 20<br/> 21 return YES;<br/> 22<br/> 23 }<br/> 24<br/> 25<br/> 26<br/> 27 /**<br/> 28<br/> 29 注册远程推送和本地通知,适配至最新系统,目前是 iOS10<br/> 30<br/> 31 */<br/> 32<br/> 33 -(void)registerRemoteNotificationsForAlliOSSystemVersion{<br/> 34<br/> 35<br/> 36<br/> 37 //<br/> 38<br/> 39<br/> 40<br/> 41<br/> 42<br/> 43 //导入文件 #import <UserNotifications/UserNotifications.h><br/> 44<br/> 45 //去capabilities(功能)设置这边打开 pushNotifications,并且打开 backgroundModes 中的backgroundFentch,Remote Notifications<br/> 46<br/> 47 CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];<br/> 48<br/> 49 if (version >= 10.0) {//10.0及其以上<br/> 50<br/> 51 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];<br/> 52<br/> 53 //请求通知权限, 本地和远程共用<br/> 54<br/> 55 // 设定通知可选提示类型<br/> 56<br/> 57 [center requestAuthorizationWithOptions:UNAuthorizationOptionCarPlay | UNAuthorizationOptionSound | UNAuthorizationOptionBadge | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {<br/> 58<br/> 59 if (error) {<br/> 60<br/> 61 NSLog(@"iOS10请求 接受远程和本地通知 授权失败:<%@>",[error description]);<br/> 62<br/> 63 }<br/> 64<br/> 65<br/> 66<br/> 67 if (granted) {<br/> 68<br/> 69 NSLog(@" iOS 10 request notification success");<br/> 70<br/> 71 NSLog(@"请求成功");<br/> 72<br/> 73 }else{<br/> 74<br/> 75 NSLog(@" iOS 10 request notification fail");<br/> 76<br/> 77 NSLog(@"请求失败");<br/> 78<br/> 79 }<br/> 80<br/> 81 }];<br/> 82<br/> 83<br/> 84<br/> 85 //设置通知的代理<br/> 86<br/> 87 center.delegate = self;//1.遵守UNUserNotificationCenterDelegate协议,2.成为代理;3.实现代理回调方法<br/> 88<br/> 89 }else if (version>=8.0){//8.0--->10.0<br/> 90<br/> 91 //请求用户授权 授权收到推送时有哪些提醒方式可以选<br/> 92<br/> 93 // 声音、角标、弹窗<br/> 94<br/> 95 UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil];<br/> 96<br/> 97 [[UIApplication sharedApplication] registerUserNotificationSettings:setting];<br/> 98<br/> 99 }else{//8.0以下<br/> 100<br/> 101 UIRemoteNotificationType type = UIRemoteNotificationTypeSound| UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge;<br/> 102<br/> 103 [[UIApplication sharedApplication] registerForRemoteNotificationTypes:type];<br/> 104<br/> 105 }<br/> 106<br/> 107<br/> 108<br/> 109 //注册通知<br/> 110<br/> 111 [[UIApplication sharedApplication] registerForRemoteNotifications];<br/> 112<br/> 113<br/> 114<br/> 115<br/> 116<br/> 117<br/> 118<br/> 119 }<br/> 120<br/> 121 #pragma mark-推送通知<br/> 122<br/> 123 //注册成功<br/> 124<br/> 125 -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{<br/> 126<br/> 127<br/> 128<br/> 129 NSString *token = [deviceToken description]; //获取<br/> 130<br/> 131<br/> 132<br/> 133 token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];<br/> 134<br/> 135 token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];<br/> 136<br/> 137 token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];<br/> 138<br/> 139<br/> 140<br/> 141 NSLog(@"request notificatoin token success. %@",token);<br/> 142<br/> 143<br/> 144<br/> 145<br/> 146<br/> 147<br/> 148<br/> 149 }<br/> 150<br/> 151 //注册失败<br/> 152<br/> 153 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error<br/> 154<br/> 155 {<br/> 156<br/> 157 NSLog(@"request notification Token fail. %@",error.localizedDescription);<br/> 158<br/> 159 }<br/> 160<br/> 161<br/> 162<br/> 163 #pragma mark iOS 10 获取推送信息 UNUserNotificationCenter---Delegate<br/> 164<br/> 165<br/> 166<br/> 167 //APP在前台的时候收到推送的回调<br/> 168<br/> 169 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler<br/> 170<br/> 171 {<br/> 172<br/> 173<br/> 174<br/> 175<br/> 176<br/> 177 UNNotificationContent *content = notification.request.content;<br/> 178<br/> 179 NSDictionary *userInfo = content.userInfo;<br/> 180<br/> 181<br/> 182<br/> 183 [self handleRemoteNotificationContent:userInfo];<br/> 184<br/> 185<br/> 186<br/> 187 //前台运行推送 显示红色Label<br/> 188<br/> 189 [self showLabelWithUserInfo:userInfo color:[UIColor redColor]];<br/> 190<br/> 191<br/> 192<br/> 193<br/> 194<br/> 195 //可以设置当收到通知后, 有哪些效果呈现(提醒/声音/数字角标)<br/> 196<br/> 197 //可以执行设置 弹窗提醒 和 声音<br/> 198<br/> 199 completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge);<br/> 200<br/> 201 }<br/> 202<br/> 203 //APP在后台,点击推送信息,进入APP后执行的回调<br/> 204<br/> 205 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler<br/> 206<br/> 207 {<br/> 208<br/> 209<br/> 210<br/> 211<br/> 212<br/> 213 UNNotificationContent *content = response.notification.request.content;<br/> 214<br/> 215 NSDictionary *userInfo = content.userInfo;<br/> 216<br/> 217<br/> 218<br/> 219 [self handleRemoteNotificationContent:userInfo];<br/> 220<br/> 221 //后台及退出推送 显示绿色Label<br/> 222<br/> 223 [self showLabelWithUserInfo:userInfo color:[UIColor greenColor]];<br/> 224<br/> 225<br/> 226<br/> 227 completionHandler();<br/> 228<br/> 229 }<br/> 230<br/> 231<br/> 232<br/> 233 - (void)handleRemoteNotificationContent:(NSDictionary *)userInfo<br/> 234<br/> 235 {<br/> 236<br/> 237 NSLog(@" iOS 10 after Notificatoin message:\n %@",userInfo);<br/> 238<br/> 239 }<br/> 240<br/> 241 #pragma mark iOS 10 之前 获取通知的信息<br/> 242<br/> 243 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{<br/> 244<br/> 245<br/> 246<br/> 247 //静默推送 显示蓝色Label<br/> 248<br/> 249 [self showLabelWithUserInfo:userInfo color:[UIColor blueColor]];<br/> 250<br/> 251<br/> 252<br/> 253 completionHandler(UIBackgroundFetchResultNewData);<br/> 254<br/> 255 }<br/> 256<br/> 257 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo<br/> 258<br/> 259 {<br/> 260<br/> 261 NSLog(@"iOS 10 before Notification message。\n %@",userInfo);<br/> 262<br/> 263 }<br/> 264<br/> 265<br/> 266<br/> 267<br/> 268<br/> 269 - (void)showLabelWithUserInfo:(NSDictionary *)userInfo color:(UIColor *)color<br/> 270<br/> 271 {<br/> 272<br/> 273 UILabel *label = [UILabel new];<br/> 274<br/> 275 label.backgroundColor = color;<br/> 276<br/> 277 label.frame = CGRectMake(0, 250, [UIScreen mainScreen].bounds.size.width, 300);<br/> 278<br/> 279 label.text = userInfo.description;<br/> 280<br/> 281 label.numberOfLines = 0;<br/> 282<br/> 283 [[UIApplication sharedApplication].keyWindow addSubview:label];<br/> 284<br/> 285 }<br/> 286<br/> 287<br/> 288<br/> 289 </em>