iOS 新特性更新汇总

iOS 12 New Features

推送分组

iOS 12 中同一类型的通知会被合成一个通知组,用户可以通过点击通知组展开组里的所有通知 jpush_ios

通知分组使用两种分组方式:自动分组(Automatic grouping)和线程标识(Thread identifier)。开发者不需要对自动分组做额外的操作,系统会根据App的 bundleId 对推送进行分组。如果需要对通知做更细致的分组就需要用上 线程标识了。 jpush_iosjpush_ios 用户可以对分组进行设置(自动、按应用、关闭)

线程标识(Thread identifier)这个属性在iOS10就已经存在,但是在iOS12才真正实现分组功能。

  1. // The unique identifier for the thread or conversation related to this notification request. It will be used to visually group notifications together.
  2. @property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier __TVOS_PROHIBITED;

摘要格式设置

通知自动分组后,在最下边会有一个消息摘要。默认格式是: 还有n个通知。这个格式是可以定制的。第一种:通过UNNotificationCategory进行格式定制

  1. + (instancetype)categoryWithIdentifier:(NSString *)identifier
  2. actions:(NSArray<UNNotificationAction *> *)actions
  3. intentIdentifiers:(NSArray<NSString *> *)intentIdentifiers
  4. hiddenPreviewsBodyPlaceholder:(nullable NSString *)hiddenPreviewsBodyPlaceholder
  5. categorySummaryFormat:(nullable NSString *)categorySummaryFormat
  6. options:(UNNotificationCategoryOptions)options __IOS_AVAILABLE(12.0) __WATCHOS_PROHIBITED;

第二种:通过UNNotificationContent进行定制

  1. /// The argument to be inserted in the summary for this notification.
  2. @property (NS_NONATOMIC_IOSONLY, readonly, copy) NSString *summaryArgument __IOS_AVAILABLE(12.0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
  3. /// A number that indicates how many items in the summary are represented in the summary.
  4. /// For example if a podcast app sends one notification for 3 new episodes in a show,
  5. /// the argument should be the name of the show and the count should be 3.
  6. /// Default is 1 and cannot be 0.
  7. @property (NS_NONATOMIC_IOSONLY, readonly, assign) NSUInteger summaryArgumentCount __IOS_AVAILABLE(12.0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;

通知管理

苹果针对消息增加了一个"管理"的按钮,消息左滑即可出现。 jpush_ios

临时授权

临时授权主要体现就是推送消息过来会有两个按钮,会主动让用户自己选择 jpush_ios

警告通知

比如家庭安全、健康、公共安全等因素的时候。此消息需要用户必须采取行动。最简单的一个场景是家里安装了一个摄像头,我们去上班了,此时如果家中有人,则摄像头会推送消息给我们。这类通知需要申请特别的证书。

jpush_ios

iOS 10 New Features

说明

iOS 10 新增了大量关于通知的新特性,详情参照极光官方的Blog。请跳转至:iOS 10 新特性

iOS 10 Service Extension

说明

iOS 10新增了Service Extension官方给出的说明图如下jpush_ios这意味着在APNs到达我们的设备之前,还会经过一层允许用户自主设置的Extension服务进行处理,为APNs增加了多样性。

使用方法

Service Extension使用起来很容易上手,首先我们需要创建一个Service Extension服务,如下图jpush_ios

然后这里需要注意几个点

  • Service Extension的Bundle Identifier不能和Main Target(也就是你自己的App Target)的Bundle Identifier相同,否则会报BundeID重复的错误。
  • Service Extension的Bundle Identifier需要在Main Target的命名空间下,比如说Main Target的BundleID为io.jpush.xxx,那么Service Extension的BundleID应该类似与io.jpush.xxx.yyy这样的格式。如果不这么做,你可能会遇到一个错误。
    那么现在你的Service Extension服务已经创建成功了,此时你已经成功的使用了Service Extension,但是好像我们还没有对它做什么操作,看看你的项目,你得到了一个类,这个类中包含两个方法。

  • didReceiveNotificationRequest:(UNNotificationRequest )request withContentHandler:(void (^)(UNNotificationContent contentToDeliver))contentHandler

  • serviceExtensionTimeWillExpire
    我们来看一下第一个方法的官方解释:Call contentHandler with the modified notification content to deliver. If the handler is not called before the service's time expires then the unmodified notification will be delivered。简单解释一下,APNs到来的时候会调用这个方法,此时你可以对推送过来的内容进行处理,然后使用contentHandler完成这次处理。但是如果时间太长了,APNs就会原样显示出来。也就是说,我们可以在这个方法中处理我们的通知,个性化展示给用户。而第二个方法,是对第一个方法的补救。第二个方法会在过期之前进行回调,此时你可以对你的APNs消息进行一下紧急处理。

iOS 9集成

iOS 9变动影响SDK部分:

  • 增加了bitCode编码格式,当SDK不支持bitCode时,用户集成时无法开启bitCode选项.
    • 现象:用户集成SDK后无法编译通过,错误日志里包含了bitCode的相关错误信息
  • 默认使用https连接,如果请求为http,需要手动配置plist来支持http服务,当前我们的服务器请求都走http服务。
    • 现象:用户集成SDK后,所有JPush相关的http服务都提示连接错误或者连接超时,可能是此问题。

bitCode解决方式

  • JPush iOS SDK v1.8.7 及以上版本的SDK,已经增加对 iOS 9 新特性 bitCode 的支持.JMessage iOS SDK v2.0.0 及以上版本支持bitCode。

Https解决方式

JPush 2.1.9及以上的版本则不需要配置此步骤

  • 需要用户主动在当前项目的Info.plist中添加NSAppTransportSecurity类型Dictionary。
  • 在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES

iOS 9 UIUserNotificationActionBehaviorTextInput

支持版本

v1.8.0 版本开始

  • 本次iOS 9在推送方面最大的变化就是修改了推送Category的类型,在原本的推送categories的基础上,增加了一个text Action类型,这个参数的目的是用来注册通过通知快捷文字输入的事项。
  • 这个categories由一系列的 UIUserNotificationCategory组成。每个UIUserNotificationCategory对象允许添加一组UIMutableUserNotificationAction类型的参数来增加通知栏上的项目。如今iOS9在原有的UIMutableUserNotificationAction类型增加了Text输入类型(UIUserNotificationActionBehaviorTextInput),通过behavior来设置(只有iOS9才拥有的属性)。
  • 回调的方法iOS9使用了两个新的回调方法来处理点击按钮的事件:
  1. - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullableNSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler NS_AVAILABLE_IOS(9_0)
  2. - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullableNSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler NS_AVAILABLE_IOS(9_0)

说明:

  • 当Action为UIUserNotificationActionBehaviorTextInput时,需要通过responseInfo的UIUserNotificationActionResponseTypedTextKey来获取输入的文字内容,UIUserNotificationTextInputActionButtonTitleKey获取点击的按钮类型.

  • 当Action为UIUserNotificationActionBehaviorDefault时,responseInfo为nil,通过identifier来区分点击按钮分别是什么来做处理.

客户端设置

设置带有快速回复内容的通知

  1. #ifdef __IPHONE_9_0
  2. UIMutableUserNotificationAction *replyAction = [[UIMutableUserNotificationAction alloc]init];
  3. replyAction.title = @"Reply";
  4. replyAction.identifier = @"comment-reply";
  5. replyAction.activationMode = UIUserNotificationActivationModeBackground;
  6. replyAction.behavior = UIUserNotificationActionBehaviorTextInput;
  7. UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc]init];
  8. category.identifier = @"reply";
  9. [category setActions:@[replyAction] forContext:UIUserNotificationActionContextDefault];
  10. #endif

使用回调函数

  1. - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler NS_AVAILABLE_IOS(9_0) {
  2. if ([identifier isEqualToString:@"comment-reply"]) {
  3. NSString *response = responseInfo[UIUserNotificationActionResponseTypedTextKey];
  4. //对输入的文字作处理
  5. }
  6. completionHandler();
  7. }

服务端设置

服务端payload格式:aps增加category字段,当该字段与客户端UIMutableUserNotificationCategory的identifier匹配时,触发设定的action和button显示。

  1. payload example:
  2. {"aps":{"alert":"example", "sound":"default", "badge": 1, "category":"reply"}}

iOS 8 UILocalNotification

本次iOS 8 UILocalNotification增加了三个参数: region、regionTriggersOnce、category。

  • region: 用于控制当用户进入或者离开某一个地理位置时候,触发通知。使用此功能,用户需要拥有CoreLocation的"when-in-use"权限。
  • regionTriggersOnce(BOOL):当为YES时,通知只会触发一次,当为NO时,通知将会在每一次进入或者离开时都触发。
  • category:如果localNotification通过+[UIUserNotificationSettings settingsForUserNotificationTypes:userNotificationActionSettings:]注册了,通过该category可以获取该通知的注册category.

客户端设置

使用UILocalNotification

  1. // set localNotification
  2. CLLocationCoordinate2D coordinate2D;
  3. coordinate2D.latitude = 100.0;
  4. coordinate2D.longitude = 100.0;
  5. CLRegion *currentRegion =
  6. [[CLCircularRegion alloc] initWithCenter:coordinate2D
  7. radius:CLLocationDistanceMax
  8. identifier:@"test"];
  9. [APService setLocalNotification:[NSDate dateWithTimeIntervalSinceNow:120]
  10. alertBody:@"test ios8 notification"
  11. badge:0
  12. alertAction:@"取消"
  13. identifierKey:@"1"
  14. userInfo:nil
  15. soundName:nil
  16. region:currentRegion
  17. regionTriggersOnce:YES
  18. category:@"test"];

iOS 8 UIUserNotificationSettings

支持版本

v1.8.0 版本开始。

  • 本次iOS 8在推送方面最大的变化就是修改了推送的注册接口,在原本的推送type的基础上,增加了一个categories参数,这个参数的目的是用来注册一组和通知关联起来的button的事件。
  • 这个categories由一系列的 UIUserNotificationCategory组成。每个UIUserNotificationCategory对象包含你的app用来响应本地或者远程通知的信息。每一个对象的title作为通知上每一个button的title展示给用户。当用户点击了某一个button,系统将会调用应用内的回调函数forRemoteNotification:completionHandler:">application:handleActionWithIdentifier:forRemoteNotification:completionHandler:或者forLocalNotification:completionHandler:">application:handleActionWithIdentifier:forLocalNotification:completionHandler:

客户端设置

使用UIUserNotificationCategory

  1. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  2. NSMutableSet *categories = [NSMutableSet set];
  3. UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
  4. category.identifier = @"identifier";
  5. UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
  6. action.identifier = @"test2";
  7. action.title = @"test";
  8. action.activationMode = UIUserNotificationActivationModeBackground;
  9. action.authenticationRequired = YES;
  10. //YES显示为红色,NO显示为蓝色
  11. action.destructive = NO;
  12. NSArray *actions = @[ action ];
  13. [category setActions:actions forContext:UIUserNotificationActionContextMinimal];
  14. [categories addObject:category];
  15. }

使用UIUserNotificationType

  1. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  2. [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:categories];
  3. }else{
  4. [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
  5. }

使用回调函数

  1. // Called when your app has been activated by the user selecting an action from
  2. // a remote notification.
  3. // A nil action identifier indicates the default action.
  4. // You should call the completion handler as soon as you've finished handling
  5. // the action.
  6. - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo
  7. completionHandler:(void (^)())completionHandler {
  8. }

服务端设置

服务端payload格式:aps增加category字段,当该字段与客户端UIMutableUserNotificationCategory的identifier匹配时,触发设定的action和button显示。

  1. payload example:
  2. {"aps":{"alert":"example", "sound":"default", "badge": 1, "category":"identifier"}}

iOS 7 Background Remote Notification

本次iOS 7在推送方面最大的变化就是允许,应用收到通知后在后台(background)状态下运行一段代码,可用于从服务器获取内容更新。功能使用场景:(多媒体)聊天,Email更新,基于通知的订阅内容同步等功能,提升了终端用户的体验。

Remote Notifications 与之前版本的对比可以参考下面两张 Apple 官方的图片便可一目了然。

jpush_ios

jpush_ios

如果只携带content-available: 1 不携带任何badge,sound 和消息内容等参数,则可以不打扰用户的情况下进行内容更新等操作即为“Silent Remote Notifications”。

jpush_ios

客户端设置

开启Remote notifications

需要在Xcode 中修改应用的 Capabilities 开启Remote notifications,请参考下图:

iOS 新特性汇总 - 图19

修改通知处理函数

当注册了Backgroud Modes -> Remote notifications 后,notification 处理函数一律切换到下面函数,后台推送代码也在此函数中调用。

  1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

服务端推送设置

推送消息携带 content-available: 1 是Background 运行的必须参数,如果不携带此字段则与iOS7 之前版本的普通推送一样。

使用Web Portal 推送

在“可选设置内”选择对应的参数。

iOS 新特性汇总 - 图20

使用 API 推送

只需在Push API v3 的 ios 内附加content-available":true 字段即可

限制与注意

  • “Silent Remote Notifications”是在 Apple 的限制下有一定的频率控制,但具体频率不详。所以并不是所有的 “Silent Remote Notifications” 都能按照预期到达客户端触发函数。
  • “Background”下提供给应用的运行时间窗是有限制的,如果需要下载较大的文件请参考 Apple 的 NSURLSession 的介绍。
  • “Background Remote Notification” 的前提是要求客户端处于Background 或 Suspended 状态,如果用户通过 App Switcher 将应用从后台 Kill 掉应用将不会唤醒应用处理 background 代码。
    更详细的说明资料请查阅 Apple 官方的 iOS 开发文档。