iOS 10 的推送 User Notifications Framework
介绍
User Notifications Framework 是苹果在 WWDC 2016 推出的。iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifications.framework 来集中管理和使用 iOS 系统中通知的功能。在此基础上,Apple 还增加了撤回单条通知,更新已展示通知,中途修改通知内容,在通知中展示图片视频,自定义通知 UI 等一系列新功能,非常强大。
iOS 10 以前的推送
iOS 10 以前推送分为 Local Notifications(本地推送) 和 Remote Notifications(远程推送)。
本地推送:通过 App 本地定制,加入到系统的 Schedule 里,然后在指定的时间推送指定文字。
远程推送:通过服务端向苹果推送服务器 Apple Push Notification Service (APNs) 发送 Notification Payload,之后 APNs 再将推送下发到指定设备的 指定 App 上。
User Notifications Framework
基本配置
如果只是简单的本地推送,跳过 1 、2 步骤,直接到步骤 3。
1、 如果你的 App 有远端推送的话,那你需要开发者账号的,需要新建一个对应你 bundle 的 push 证书。 具体的证书制作请参考这里
2、 Capabilities 中打开 Push Notifications 开关在 XCode7 中这里的开关不打开,推送也是可以正常使用的,但是在 XCode8 中,这里的开关必须要打开,不然会报错:
Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串" UserInfo={NSLocalizedDescription=未找到应用程序的“aps-environment”的授权字符串}
权限申请
在使用 UserNotifications 框架的 API 的时候,首先要导入 UserNotifications 框架:
#import <UserNotifications/UserNotifications.h>
注册推送
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error) { NSLog(@"请求授权成功"); } else { NSLog(@"请求授权失败"); } }];
Notification settings:之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意 UNNotificationSettings 是只读对象哦,不能直接修改!只能通过以下方式获取
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { NSLog(@"%@", settings); }];
打印
<UNNotificationSettings: 0x6000022f9dc0; authorizationStatus: NotDetermined, notificationCenterSetting: NotSupported, soundSetting: NotSupported, badgeSetting: NotSupported, lockScreenSetting: NotSupported, carPlaySetting: NotSupported, criticalAlertSetting: NotSupported, alertSetting: NotSupported, alertStyle: None, providesAppNotificationSettings: No>
Token Registration
[[UIApplication sharedApplication] registerForRemoteNotifications];
获取设备的Device Token
/获取DeviceToken成功 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"deviceToken:%@",deviceString); } //获取DeviceToken失败 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"[DeviceToken Error]:%@\n",error.description); }
接收推送的代理方法
// App处于前台接收通知时 // 只有app处于前台状态下才会调用,后台状态或者应用杀死下是不会调用这个方法的 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler // App通知的点击事件 // 用户点击消息才会触发 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler
苹果把本地通知跟远程通知合二为一。区分本地通知跟远程通知的类是UNPushNotificationTrigger.h 类中,UNPushNotificationTrigger 的类型是新增加的。
UNPushNotificationTrigger (远程通知) 远程推送的通知类型
UNTimeIntervalNotificationTrigger (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。
UNCalendarNotificationTrigger(本地通知) 一定日期之后,重复或者不重复推送通知 例如,你每天8点推送一个通知,只要dateComponents为8,如果你想每天8点都推送这个通知,只要repeats为YES就可以了。
UNLocationNotificationTrigger (本地通知)地理位置的一种通知,
当用户进入或离开一个地理区域来通知。
内容
以前只能展示一条文字,现在可以有 title 、subtitle 以及 body 了。
定制方法如下:
//本地通知 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"CALENDAR"; content.subtitle = @"Lunch"; content.body = @"Today at 12:00 PM"; content.badge = @1; //远程推送 { "aps" : { "alert" : { "title" : "CALENDAR", "subtitle" : "Lunch", "body" : "Today at 12:00 PM" }, "badge" : 1 }, }
Triggers
UNTimeIntervalNotificationTrigger 定时推送
UNCalendarNotificationTrigger 定期推送
UNLocationNotificationTrigger 定点推送
//60 秒后提醒 //timeInterval:单位为秒(s) repeats:是否循环提醒 UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:60 repeats:NO]; // 在每周一早上 8:00 提醒 NSDateComponents *components = [[NSDateComponents alloc] init]; components.weekday = 2; components.hour = 8; UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES]; //首先得导入#import <CoreLocation/CoreLocation.h>,不然会regin创建有问题。 CLLocationCoordinate2D center1 = CLLocationCoordinate2DMake(31.234567, 117.4567890); CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center1 radius:500 identifier:@"桂林路"]; UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
Add Request
NSString *requestIdentifier = @"sampleRequest"; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:trigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
推送小结
整个推送的过程如下
Local Notifications 通过定义 Content 和 Trigger 向 UNUserNotificationCenter 进行 request 这三部曲来实现。
Remote Notifications 则向 APNs 发送 Notification Payload 。
Notification Handling
设定了推送,然后就结束了?iOS 10 并没有这么简单!
通过实现协议,使 App 处于前台时捕捉并处理即将触发的推送:
@interface AppDelegate () <UNUserNotificationCenterDelegate> - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound); }
让它只显示 alert 和 sound ,而忽略 badge 。
Notification Management
彻底掌控整个推送周期:
Local Notification 通过更新 request
Remote Notification 通过新的字段 apns-collapse-id
通过之前的 addNotificationRequest: 方法,在 id 不变的情况下重新添加,就可以刷新原有的推送。
NSString *requestIdentifier = @"sampleRequest"; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:newContent trigger:newTrigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
删除计划的推送:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
此外 UNUserNotificationCenter.h 中还有诸如删除所有推送、查看已经发出的推送、删除已经发出的推送等等强大的接口。
刷新原有的推送后,在通知中心的显示里,也会有相应的变化,这里注意第 2 条信息,现在比分是 1:0
比分刷新后为 1:1,在不产生新的推送条目的情况下位置被前置了!
上面简单介绍了 iOS 10 的新框架 User Notifications Framework,了解完 iOS 10 的框架之后,还要适配iOS 8 9 系统,是不是觉得很麻烦,笔者最近发现了一款 SDK ---- MobPush,兼容 iOS 8-12 系统,接入非常简单,3行代码就可以搞定推送。
MPushNotificationConfiguration *configuration = [[MPushNotificationConfiguration alloc] init]; configuration.types = MPushAuthorizationOptionsBadge | MPushAuthorizationOptionsSound | MPushAuthorizationOptionsAlert; [MobPush setupNotification:configuration];
同时,MobPush 支持多样化推送场景、用户分群、AB 测试、智能推送等等功能,还有完善的数据统计后台可以从多个维度实时了解 APP 和用户的使用情况
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android开发 - 掌握ConstraintLayout(一)传统布局的问题
在传统的Android开发中,页面布局占用了我们很多的开发时间,而且面对复杂页面的时候,传统的一些布局会显得非常复杂,每种布局都有特定的应用场景,我们通常需要各种布局结合起来使用来实现复杂的页面。随着ConstraintLayout的推出,这种现象有了很大的改善,而且它可以实现很多传统布局难以实现的功能。 本系列我们就一起来学习ConstraintLayout的使用,来大幅提高我们的生产力。 传统布局 在ConstraintLayout退出之前,我们经常使用FrameLayout, LinearLayout, RelativeLayout, *Layout等来布局页面。这些布局当然有其方便的地方,但是其方便地同时也限制了我们的使用场景,在写一些复杂页面的时候就显得力不从心,我们先做一下简单地回顾: FrameLayout:帧布局。最常用并且简单的布局,通常用于错误页面的显示,蒙层的显示等。 LinearLayout:线性布局。当我们绘制需要顺序排列的内容时,我们使用使用此布局。 RelativeLayout:相对布局。相当于ConstraintLayout的低级版本。顾名思义,可以各个...
- 下一篇
Android Gradle 插件开发指南
作为Android开发者,你可能见过无数个apply plugin:plugin_name,plugin_name对应着相应的插件。 例如: apply plugin: 'com.android.application' apply plugin: 'com.android.library' com.android.application就对应着可以一个构建APK的Gradle插件,而com.android.library则对应着一个构建android library的插件。 Gradle插件开发支持Java、Groovy、Scala三种语言开发,Groovy用于实现与 Gradle 构建生命周期(如 task 的依赖)有关的逻辑,Java用于核心逻辑,表现为 Groovy 调用 Java 的代码。 插件的打包方式 Gradle的插件有三种打包方式,主要是按照复杂程度和可见性来划分: 类型 说明 Build script 把插件写在 build.gradle 文件中,一般用于简单的逻辑,只在该 build.gradle 文件中可见 buildSrc 项目 将插件源代码放在 rootPr...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS6,CentOS7官方镜像安装Oracle11G
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作