iOS 10 的推送 User Notifications Fr

2018-10-30  本文已影响0人  皮皮酱ye

介绍

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 和用户的使用情况,了解更多

上一篇下一篇

猜你喜欢

热点阅读