一、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时: 发送UDIDBundleIDAPNs加密后返回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中, 还需要设置UNUserNotificationCenterdelegate, 并遵守UNUserNotificationCenterDelegate协议.

以及实现下面实现3个方法, 用于处理点击通知时的不同情况的处理

willPresentNotification:withCompletionHandler 用于前台运行

didReceiveNotificationResponse:withCompletionHandler 用于后台及程序退出

didReceiveRemoteNotification:fetchCompletionHandler用于静默推送

1.前台运行 会调用的方法

前台运行: 指的是程序正在运行中, 用户能看见程序的界面.

iOS10会出现通知横幅, 而在以前的框架中, 前台运行时, 不会出现通知的横幅.

代码开始前的设置 

iOS 10 的推送 与原来的都不一样,他把本地的推送 跟 远程的推送结合到一起了,UserNotifications.framework 库。在使用推送的时候,先开启通知的开关。

就是上面这个。当你开启后,xcode 会自动帮你在 项目里面创建一个文件,xxxx.entitlements.

这个文件是系统帮你创建的,不用管它。

在appDeletgate 文件里面需要先导入 UNUserNotificationCenterDelegate 这个代理。他的代理方法分别是

  1. – (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
  2. – (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>