前言

之前说会单独整理消息通知的内容,但是因为工(就)作(是)的(很)事(懒)没有更新文章,违背了自己的学习的初衷。因为互联网一定要有危机意识,说不定眼一睁,我们就out丢了饭碗。

图片来源网络.jpeg

“狼,他没有狮子老虎强壮,也没有大象那庞大的身躯,但至少:我从来没在马戏团看到过他们的身影。”

也许只有狼在一直奔跑,这是我一直喜欢它的原因,要像狼一样不断奔跑,才能幸存!

看完楼主装的一手好X,我来总结一点点你都知道的通知方面的知识点!

楼主装逼,打他.jpg

背景

iOS10 新特性一出,各个大神就早已研究新特性能给场景智能化所带来的好处(唉,可惜我只是一个小白)。我也被安排适配iOS10的推送工作!

Apple 表示这是 iOS 有史以来最大的升级(our biggest release yet),更加智能开放的 Siri 、强化应用对 3D Touch 支持、 HomeKit 、电话拦截及全新设计的通知等等…

iOS 10 中将之前繁杂的推送通知统一成UserNotifications.framework 来集中管理和使用通知功能,还增加一些实用的功能——撤回单条通知、更新已展示通知、中途修改通知内容、在通知中显示多媒体资源、自定义UI等功能,功能着实强大!

本文主要是针对iOS 10的消息通知做介绍,所以很多代码没有对iOS 10之前做添加适配。

基本原理

iOS推送分为Local Notifications(本地推送) 和 Remote Notifications(远程推送)(原理图来源于网络,如有侵权请告知,我会添加来源,我怕我赔不起)

Local Notifications(本地推送)

Local Notifications.png
  1. App本地创建通知,加入到系统的Schedule里,
  2. 如果触发器条件达成时会推送相应的消息内容

Remote Notifications(远程推送)

Remote Notifications1.jpg

图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用我花了12块大洋(心疼)买的 APNS Pusher 作为我的推送源。

APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。

上图可以分为三个阶段:

第一阶段:APNS Pusher应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。

第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。

第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。

Remote Notifications2.jpeg

从上图我们可以看到:

  1. 首先是应用程序注册消息推送。

  2. IOS跟APNS Server要deviceToken。应用程序接受deviceToken。

  3. 应用程序将deviceToken发送给PUSH服务端程序。

  4. 服务端程序向APNS服务发送消息。

  5. APNS服务将消息发送给iPhone应用程序。

基本配置和基本方法

如果只是简单的本地推送,跳过1 2 步骤,直接到3

1、 如果你的App有远端推送的话,那你需要开发者账号的,需要新建一个对应你bundle的push 证书。证书这一块我就不说了,如果针对证书有什么问题可以给我留言,我会单独把证书相关的知识点整理起来!如果你没有账号,可以到某宝买个,很便宜。
2、 Capabilities中打开Push Notifications 开关
在XCode7中这里的开关不打开,推送也是可以正常使用的,但是在XCode8中,这里的开关必须要打开,不然会报错:

  1. Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串" UserInfo={NSLocalizedDescription=未找到应用程序的“aps-environment”的授权字符串}

打开后会自动在项目里生成entitlements文件。

Push Notification开关.png

entitlements文件.png

3、 推送的注册

第一步: 导入 #import <UserNotifications/UserNotifications.h>
且要遵守<UNUserNotificationCenterDelegate>的协议,在Appdelegate.m中。
这里需要注意,我们最好写成这种形式(防止低版本找不到头文件出现问题)

  1. #ifdef NSFoundationVersionNumber_iOS_9_x_Max
  2. #import <UserNotifications/UserNotifications.h>
  3. #endif

第二步:我们需要在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中注册通知,代码如下

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  2. [self replyPushNotificationAuthorization:application];
  3. return YES;
  4. }
  5. #pragma mark - 申请通知权限
  6. // 申请通知权限
  7. - (void)replyPushNotificationAuthorization:(UIApplication *)application{
  8. if (IOS10_OR_LATER) {
  9. //iOS 10 later
  10. UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  11. //必须写代理,不然无法监听通知的接收与点击事件
  12. center.delegate = self;
  13. [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
  14. if (!error && granted) {
  15. //用户点击允许
  16. NSLog(@"注册成功");
  17. }else{
  18. //用户点击不允许
  19. NSLog(@"注册失败");
  20. }
  21. }];
  22. // 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置
  23. //之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!
  24. [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
  25. NSLog(@"========%@",settings);
  26. }];
  27. }else if (IOS8_OR_LATER){
  28. //iOS 8 - iOS 10系统
  29. UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
  30. [application registerUserNotificationSettings:settings];
  31. }else{
  32. //iOS 8.0系统以下
  33. [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
  34. }
  35. //注册远端消息通知获取device token
  36. [application registerForRemoteNotifications];
  37. }

上面需要注意:

  1. 1. 必须写代理,不然无法监听通知的接收与点击事件
  2. center.delegate = self;
  3. 下面是我在项目里定义的宏
  4. #define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)
  5. #define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0)
  6. #define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
  7. #define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
  8. 2. 之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!只能通过以下方式获取
  9. [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
  10. NSLog(@"========%@",settings);
  11. }];
  12. 打印信息如下:
  13. ========<UNNotificationSettings: 0x1740887f0; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, alertSetting: NotSupported, carPlaySetting: Enabled, alertStyle: Banner>

4、 远端推送需要获取设备的Device Token的方法是没有变的,代码如下

  1. #pragma mark - 获取device Token
  2. //获取DeviceToken成功
  3. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
  4. //解析NSData获取字符串
  5. //我看网上这部分直接使用下面方法转换为string,你会得到一个nil(别怪我不告诉你哦)
  6. //错误写法
  7. //NSString *string = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];
  8. //正确写法
  9. NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
  10. deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""];
  11. NSLog(@"deviceToken===========%@",deviceString);
  12. }
  13. //获取DeviceToken失败
  14. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
  15. NSLog(@"[DeviceToken Error]:%@\n",error.description);
  16. }

5、这一步吊了,这是iOS 10系统更新时,苹果给了我们2个代理方法来处理通知的接收和点击事件,这两个方法在<UNUserNotificationCenterDelegate>的协议中,大家可以查看下。

  1. @protocol UNUserNotificationCenterDelegate <NSObject>
  2. @optional
  3. // The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
  4. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
  5. // The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from applicationDidFinishLaunching:.
  6. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
  7. @end

此外,苹果把本地通知跟远程通知合二为一。区分本地通知跟远程通知的类是UNPushNotificationTrigger.h类中,UNPushNotificationTrigger的类型是新增加的,通过它,我们可以得到一些通知的触发条件 ,解释如下:

  1. UNPushNotificationTrigger (远程通知) 远程推送的通知类型
  2. UNTimeIntervalNotificationTrigger (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。
  3. UNCalendarNotificationTrigger(本地通知) 一定日期之后,重复或者不重复推送通知 例如,你每天8点推送一个通知,只要dateComponents为8,如果你想每天8点都推送这个通知,只要repeats为YES就可以了。
  4. UNLocationNotificationTrigger (本地通知)地理位置的一种通知,
    当用户进入或离开一个地理区域来通知。
    现在先提出来,后面我会一一代码演示出每种用法。还是回到两个很吊的代理方法吧
  1. #pragma mark - iOS10 收到通知(本地和远端) UNUserNotificationCenterDelegate
  2. //App处于前台接收通知时
  3. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
  4. //收到推送的请求
  5. UNNotificationRequest *request = notification.request;
  6. //收到推送的内容
  7. UNNotificationContent *content = request.content;
  8. //收到用户的基本信息
  9. NSDictionary *userInfo = content.userInfo;
  10. //收到推送消息的角标
  11. NSNumber *badge = content.badge;
  12. //收到推送消息body
  13. NSString *body = content.body;
  14. //推送消息的声音
  15. UNNotificationSound *sound = content.sound;
  16. // 推送消息的副标题
  17. NSString *subtitle = content.subtitle;
  18. // 推送消息的标题
  19. NSString *title = content.title;
  20. if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
  21. //此处省略一万行需求代码。。。。。。
  22. NSLog(@"iOS10 收到远程通知:%@",userInfo);
  23. }else {
  24. // 判断为本地通知
  25. //此处省略一万行需求代码。。。。。。
  26. NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
  27. }
  28. // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
  29. completionHandler(UNNotificationPresentationOptionBadge|
  30. UNNotificationPresentationOptionSound|
  31. UNNotificationPresentationOptionAlert);
  32. }
  33. //App通知的点击事件
  34. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
  35. //收到推送的请求
  36. UNNotificationRequest *request = response.notification.request;
  37. //收到推送的内容
  38. UNNotificationContent *content = request.content;
  39. //收到用户的基本信息
  40. NSDictionary *userInfo = content.userInfo;
  41. //收到推送消息的角标
  42. NSNumber *badge = content.badge;
  43. //收到推送消息body
  44. NSString *body = content.body;
  45. //推送消息的声音
  46. UNNotificationSound *sound = content.sound;
  47. // 推送消息的副标题
  48. NSString *subtitle = content.subtitle;
  49. // 推送消息的标题
  50. NSString *title = content.title;
  51. if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
  52. NSLog(@"iOS10 收到远程通知:%@",userInfo);
  53. //此处省略一万行需求代码。。。。。。
  54. }else {
  55. // 判断为本地通知
  56. //此处省略一万行需求代码。。。。。。
  57. NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
  58. }
  59. //2016-09-27 14:42:16.353978 UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
  60. completionHandler(); // 系统要求执行这个方法
  61. }

需要注意的:

  1. 1.下面这个代理方法,只会是app处于前台状态 前台状态 and 前台状态下才会走,后台模式下是不会走这里的
  2. - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
  3. 2.下面这个代理方法,只会是用户点击消息才会触发,如果使用户长按(3DTouch)、弹出Action页面等并不会触发。点击Action的时候会触发!
  4. - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
  5. 3.点击代理最后需要执行:completionHandler(); // 系统要求执行这个方法
  6. 不然会报:
  7. 2016-09-27 14:42:16.353978 UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
  8. 4.不管前台后台状态下。推送消息的横幅都可以展示出来!后台状态不用说,前台时需要在前台代理方法中设置 ,设置如下:
  9. // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
  10. completionHandler(UNNotificationPresentationOptionBadge|
  11. UNNotificationPresentationOptionSound|
  12. UNNotificationPresentationOptionAlert);

6、 iOS 10之前接收通知的兼容方法

  1. #pragma mark -iOS 10之前收到通知
  2. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  3. NSLog(@"iOS6及以下系统,收到通知:%@", userInfo);
  4. //此处省略一万行需求代码。。。。。。
  5. }
  6. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  7. NSLog(@"iOS7及以上系统,收到通知:%@", userInfo);
  8. completionHandler(UIBackgroundFetchResultNewData);
  9. //此处省略一万行需求代码。。。。。。
  10. }

段结:是不是以为就结束了?NO NO NO(你以为离开了幻境,其实才刚刚踏入幻境!)上面的介绍了基本原理、基本配置以及基本方法说明,现在做完这些工作,我们的学习才刚刚开始!现在天时、地利、人和、可以开始下面推送coding的学习和测试了。

在用户日常生活中会有很多种情形需要通知,比如:新闻提醒、定时吃药、定期体检、到达某个地方提醒用户等等,这些功能在 UserNotifications 中都提供了相应的接口。

图片来源于网络.jpeg

我们先学会基本的技能简单的推送(爬),后面在学习进阶定制推送(走),最后看看能不能高级推送(飞不飞起来看个人了,我是飞不起来):

基本Local Notifications(本地推送) 和 Remote Notifications(远程推送)

一、 基本的本地推送

本地推送生成主要流程就是:

  1. 1. 创建一个触发器(trigger
  2. 2. 创建推送的内容(UNMutableNotificationContent
  3. 3. 创建推送请求(UNNotificationRequest
  4. 4. 推送请求添加到推送管理中心(UNUserNotificationCenter)中

1、新功能trigger可以在特定条件触发,有三类:UNTimeIntervalNotificationTrigger、UNCalendarNotificationTrigger、UNLocationNotificationTrigger

1.1、 UNTimeIntervalNotificationTrigger:一段时间后触发(定时推送

  1. //timeInterval:单位为秒(s) repeats:是否循环提醒
  2. //50s后提醒
  3. UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:50 repeats:NO];

1.2 UNCalendarNotificationTrigger :调用
+ (instancetype)triggerWithDateMatchingComponents:(NSDateComponents *)dateComponents repeats:(BOOL)repeats;进行注册;时间点信息用 NSDateComponents.(定期推送

  1. //在每周一的14点3分提醒
  2. NSDateComponents *components = [[NSDateComponents alloc] init];
  3. components.weekday = 2;
  4. components.hour = 16;
  5. components.minute = 3;
  6. // components 日期
  7. UNCalendarNotificationTrigger *calendarTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];

1.3、UNLocationNotificationTrigger:调用
+ (instancetype)triggerWithRegion:(CLRegion *)region repeats:(BOOL)repeats;
进行注册,地区信息使用CLRegion的子类CLCircularRegion,可以配置region属性 notifyOnEntrynotifyOnExit,是在进入地区、从地区出来或者两者都要的时候进行通知,这个测试过程专门从公司跑到家时刻关注手机有推送嘛,果然是有的(定点推送

  1. //首先得导入#import <CoreLocation/CoreLocation.h>,不然会regin创建有问题。
  2. // 创建位置信息
  3. CLLocationCoordinate2D center1 = CLLocationCoordinate2DMake(39.788857, 116.5559392);
  4. CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center1 radius:500 identifier:@"经海五路"];
  5. region.notifyOnEntry = YES;
  6. region.notifyOnExit = YES;
  7. // region 位置信息 repeats 是否重复 (CLRegion 可以是地理位置信息)
  8. UNLocationNotificationTrigger *locationTrigger = [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES];

2、创建推送的内容(UNMutableNotificationContent)
UNNotificationContent:属性readOnly
UNMutableNotificationContent:属性有title、subtitle、body、badge、sound、lauchImageName、userInfo、attachments、categoryIdentifier、threadIdentifier

本地消息内容 内容限制大小 展示
title NSString 限制在一行,多出部分省略号
subtitle NSString 限制在一行,多出部分省略号
body NSString 通知栏出现时,限制在两行,多出部分省略号;预览时,全部展示

注意点: body中printf风格的转义字符,比如说要包含%,需要写成%% 才会显示,\同样

  1. // 创建通知内容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此对象为不可变对象。
  2. UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
  3. content.title = @"Dely 时间提醒 - title";
  4. content.subtitle = [NSString stringWithFormat:@"Dely 装逼大会竞选时间提醒 - subtitle"];
  5. content.body = @"Dely 装逼大会总决赛时间到,欢迎你参加总决赛!希望你一统X界 - body";
  6. content.badge = @666;
  7. content.sound = [UNNotificationSound defaultSound];
  8. content.userInfo = @{@"key1":@"value1",@"key2":@"value2"};

3、创建完整的本地推送请求Demo

  1. //定时推送
  2. + (void)createLocalizedUserNotification{
  3. // 设置触发条件 UNNotificationTrigger
  4. UNTimeIntervalNotificationTrigger *timeTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0f repeats:NO];
  5. // 创建通知内容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此对象为不可变对象。
  6. UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
  7. content.title = @"Dely 时间提醒 - title";
  8. content.subtitle = [NSString stringWithFormat:@"Dely 装逼大会竞选时间提醒 - subtitle"];
  9. content.body = @"Dely 装逼大会总决赛时间到,欢迎你参加总决赛!希望你一统X界 - body";
  10. content.badge = @666;
  11. content.sound = [UNNotificationSound defaultSound];
  12. content.userInfo = @{@"key1":@"value1",@"key2":@"value2"};
  13. // 创建通知标示
  14. NSString *requestIdentifier = @"Dely.X.time";
  15. // 创建通知请求 UNNotificationRequest 将触发条件和通知内容添加到请求中
  16. UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger];
  17. UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
  18. // 将通知请求 add 到 UNUserNotificationCenter
  19. [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
  20. if (!error) {
  21. NSLog(@"推送已添加成功 %@", requestIdentifier);
  22. //你自己的需求例如下面:
  23. UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"本地通知" message:@"成功添加推送" preferredStyle:UIAlertControllerStyleAlert];
  24. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
  25. [alert addAction:cancelAction];
  26. [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
  27. //此处省略一万行需求。。。。
  28. }
  29. }];
  30. }

运行结果如下:

装X决赛通知.jpg

二、 基本的远端推送
如果你想模拟远端推送,按照我前面介绍的配置基本环境、证书、push开关和基本方法就可以模拟远端的基本远端推送。
1、运行工程则会拿到设备的Device Token,后面会用到。

device token.png

2、现在我们需要一个推送服务器给APNS发送信息。我前面说了我花了12块大洋(心疼死我了)买了一个APNS pusher 来模拟远端推送服务,当然你可以不花钱也可以用到,例如:
NWPusher

APNS pusher

3、你需要把你刚刚获取的device token填到相应位置,同时你要配置好push证书哦。

4、需要添加aps内容了,然后点击send就OK了

  1. {
  2. "aps" : {
  3. "alert" : {
  4. "title" : "iOS远程消息,我是主标题!-title",
  5. "subtitle" : "iOS远程消息,我是主标题!-Subtitle",
  6. "body" : "Dely,why am i so handsome -body"
  7. },
  8. "badge" : "2"
  9. }
  10. }

5、稍纵即逝你就收到了远端消息了

远端消息.jpg

6、Notification Management
对推送进行查、改、删。都需要一个必需的参数requestIdentifier

1、更新通知

Local Notification需要通过更新request.相同的requestIdentifier,重新添加到推送center就可以了,说白了就是重新创建local Notification request(只要保证requestIdentifier就ok了),应用场景如图

Local Notification更新前.png

Local Notification更新后.png

Remote Notification 更新需要通过新的字段apps-collapse-id来作为唯一标示,我前面用的APNS pusher暂不支持这个字段,不过github上有很多这样的工具:
https://github.com/KnuffApp/Knuff
这样remote 也可以更新推送消息

2、推送消息的查找和删除

  1. // Notification requests that are waiting for their trigger to fire
  2. //获取未送达的所有消息列表
  3. - (void)getPendingNotificationRequestsWithCompletionHandler:(void(^)(NSArray<UNNotificationRequest *> *requests))completionHandler;
  4. //删除所有未送达的特定id的消息
  5. - (void)removePendingNotificationRequestsWithIdentifiers:(NSArray<NSString *> *)identifiers;
  6. //删除所有未送达的消息
  7. - (void)removeAllPendingNotificationRequests;
  8. // Notifications that have been delivered and remain in Notification Center. Notifiations triggered by location cannot be retrieved, but can be removed.
  9. //获取已送达的所有消息列表
  10. - (void)getDeliveredNotificationsWithCompletionHandler:(void(^)(NSArray<UNNotification *> *notifications))completionHandler __TVOS_PROHIBITED;
  11. //删除所有已送达的特定id的消息
  12. - (void)removeDeliveredNotificationsWithIdentifiers:(NSArray<NSString *> *)identifiers __TVOS_PROHIBITED;
  13. //删除所有已送达的消息
  14. - (void)removeAllDeliveredNotifications __TVOS_PROHIBITED;

测试如下:

  1. + (void)notificationAction{
  2. NSString *requestIdentifier = @"Dely.X.time";
  3. UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
  4. //删除设备已收到的所有消息推送
  5. // [center removeAllDeliveredNotifications];
  6. //删除设备已收到特定id的所有消息推送
  7. // [center removeDeliveredNotificationsWithIdentifiers:@[requestIdentifier]];
  8. //获取设备已收到的消息推送
  9. [center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
  10. }];
  11. }

段结: 收到通知时你需要在appdelegate里面的代理方法里处理你的需求逻辑,这个需要你自己写了。到目前为止你掌握了基本的本地推送基本的远端推送!

不知不觉写了这么多字(全是TM废话)、本来继续打算写进阶的本地和远端推送(Media Attachments、Notification Actions、自定义推送界面等),留着下一篇博客继续分享吧,欲知后事如何,且听下会装X!

如果你喜欢可以点个喜欢^_^(竟有如此厚颜无耻之人)

下集预告:

推送图片.jpg

推送图片2.jpg

参考资料:
https://developer.apple.com/reference/usernotifications
http://www.jianshu.com/p/b74e52e866fc
http://www.jianshu.com/p/b74e52e866fc
http://blog.csdn.net/he317165264/article/details/52574934
http://qoofan.com/read/PnEaMEZonD.html
http://www.qingpingshan.com/rjbc/ios/140921.html

文/Dely(简书作者)
原文链接:http://www.jianshu.com/p/c58f8322a278
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

iOS 10 消息推送(UserNotifications)秘籍总结(一)的更多相关文章

  1. iOS 10 消息推送(UserNotifications)秘籍总结(二)

    背景 上一篇博客iOS 10 消息推送(UserNotifications)秘籍总结(一)发布后被 简书编辑推荐至首页,这着实让我受宠若惊啊.可是好事不长,后面发生了让我伤心欲绝的事,我的女朋友不要我 ...

  2. iOS开发消息推送原理

    转载自:http://www.cnblogs.com/cdts_change/p/3240893.html 一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Prov ...

  3. iOS 之消息推送(个推)---个人小结

    前言:自从上个星期开始整这个推送,弄了差不多一个星期,今天终于给整好了,因此现在来记录这段"奇妙"的旅程. 我们公司使用的消息推送是用的第三方--个推,这里不得不说一下,个推的技术 ...

  4. 分分钟搞定IOS远程消息推送

    一.引言 IOS中消息的推送有两种方式,分别是本地推送和远程推送,本地推送在http://my.oschina.net/u/2340880/blog/405491这篇博客中有详细的介绍,这里主要讨论远 ...

  5. iOS开发——消息推送跳转

    项目开发用集成是极光推送JPush     这里主要是消息推送过来处理对应界面跳转          同时看到两篇写的不错的相关博客分享一下:      http://www.jianshu.com/ ...

  6. iOS 远程消息推送,原理和开发详解篇(新手推荐)

    1.APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Servic ...

  7. iOS远程消息推送原理

    1. 什么是远程消息推送? APNs:Apple Push Notification server 苹果推送通知服务苹果的APNs允许设备和苹果的推送通知服务器保持连接,支持开发者推送消息给用户设备对 ...

  8. iOS远程消息推送自我整理版

    @interface AppDelegate () <UIApplicationDelegate> @end @implementation AppDelegate - (BOOL)app ...

  9. 玩转iOS开发 - 消息推送

    消息推送

随机推荐

  1. DataSet.Clear Method ()

    Clears the DataSet of any data by removing all rows in all tables. 需要注意的是这个方法不会清空DataSet中的DataTable, ...

  2. V-rep学习笔记:转动关节1

    V-REP(Virtual Robot Experimentation Platform),是全球领先的机器人及模拟自动化软件平台.V-REP让使用者可以模拟整个机器人系统或其子系统(如感测器或机械结 ...

  3. Pre-Query trigger in Oracle D2k / Oracle Forms

    Pre-Query trigger in Oracle D2k / Oracle Forms DescriptionFires during Execute Query or Count Query ...

  4. EasyUI--messager

    1. alert 方法 <script type="text/javascript"> $( function() { $.messager.alert("调 ...

  5. CUBRID学习笔记 15 Lobs类型数据

    BLOB: Binary large object CLOB: Character large object 一个二进制 一个字符类型 二进制的读取 CUBRIDCommand cmd = new C ...

  6. javascript中获取非行间样式的方法

    我们都知道一般在javascript中获取样式一般用的是nodeObj.style.attr这个属性的,但是这个属性只能获取行间样式非行间样式比如写在样式表中的样式那么用nodeObj.style.a ...

  7. 16位的MD5加密和32位MD5加密的区别

    16位的MD5加密和32位MD5加密的区别 MD5加密后所得到的通常是32位的编码,而在不少地方会用到16位的编码它们有什么区别呢?16位加密就是从32位MD5散列中把中间16位提取出来!其实破解16 ...

  8. 阿里商业评论 | 互联网POI数据及其在营销中的应用

    阿里商业评论 | 互联网POI数据及其在营销中的应用 时间 2014-11-05 10:40:50  阿里研究院 原文  http://www.aliresearch.com/index.php?m- ...

  9. Target runtime Apache Tomcat v7.0 is not defined.

    打开项目,找到.settings--->org.eclipse.wst.common.project.facet.core 修改这个文件中: <?xml version="1.0 ...

  10. Linux进程空间分布 & 进程控制块 PCB

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Verdana; color: #555555 } span.s1 { } Linux使用两级 ...