推送通知(二)-iOS>10的推送通知

接下来主要讲的是iOS10的推送通知

简介

  1. iOS10有如下几项改进:
    1. iOS 8以后,APNs推送的字节是2k,iOS8以前是256字节,iOS10现在是4k
    2. iOS 9以后APNs支持HTTP/2协议栈,优化长连接,具有标准的HTTP返回和管道复用技术
    3. iOS 10以后,APNs可根据推送消息的唯一标示符查询某条消息是否被用户阅读,可更新某一推送消息,而不用发重读的多条消息
  2. iOS10新加了一个独立框架:UserNotification.framework,废弃了 UILocalNotification(在UIKit.framework中)这个类,采用了全新的UserNotifications.framework来推送通知,从此推送通知也有了自己的标签UN(,以及对推送功能的一系列增强改进(两个extension,延展)和界面的体验优化)。
  3. iOS10的通知新功能
    1. iOS 10通知系统支持Images, GIFs, Audio and Video类型
    2. iOS 10推出Notification Service Extension与Notification Content Extension,可以实现推送数据在展示前进行下载更新、定制通知UI
    3. iOS 10统一了通知类型,具有时间间隔通知、地理位置通知和日历通知
  4. 废话不多说,学习一个新的框架当然就是从他常用的类开始

常见类之间的关系

  1. 该框架的类的结构分为2部分
    1. 管理通知相关的类
      图1
    2. 创建通知相关的类
      图1
    3. 常见类分析:
      1. UNUserNotificationCenter通知中心,用以管理通知的注册、权限获取和管理、通知的删除与更新,通过代理分发事件等。
      2. UNNotification 通知实体,在UNUserNotificationCenter的代理回调事件中,告知App接收到一条通知,包含一个发起通知的请求UNNotificationRequest
      3. UNNotificationRequest包含通知内容UNNotificationContent和触发器UNNotificationTrigger
      4. UNNotificationContent 通知内容,通知的title,sound,badge以及相关的图像、声音、视频附件UNNotificationAttachment,触发打开App时候指定的LacnchImage等
      5. UNNotificationResponse,用户在触发了按钮或者文本提交的UNNotificationAction的时候,会形成一个response,通过通知中心的代理方法回调给App进行处理或者是交给扩展处理。
      6. UNNotificationServiceExtension,是一个在接收到APNs服务器推送过来的数据进行处理的服务扩展,如果App提供了服务扩展,那么APNs下发推送后在通知显示触发之前,会在UNNotificationServiceExtension内接收到,此处有大约30秒的处理时间,开发者可以进行一些数据下载、数据解密、更新等操作,然后交由而后的内容扩展(UNNotificationContentExtension)或者是App进行触发显示
      7. UNNotificationCategory,用以定义一组样式类型,该分类包含了某一个通知包含的交互动作的组合,比如说UNNotificationRequest内包含了一个Category标示,那该通知就会以预定义好的交互按钮或者文本框添加到通知实体上。
      8. UNNotificationAttachment,通知内容UNNotificationContent包含的附件,一般为图片、视频和音频,虽然iOS10的通知数据容量为4k,但依旧很少,在添加了UNNotificationServiceExtension扩展的情况下,可以在服务里下载图片,生成图片、视频等的本地缓存,UNNotificationAttachment根据缓存数据生成并添加到UNNotificationContent中,交由UI显示
      9. UNNotificationAction,是通知中添加的action,展示在通知栏的下方。默认以的button样式展示。有一个文本输入的子类UNTextInputNotificationAction。可以在点击button之后弹出一个键盘,输入信息。用户点击信息和输入的信息可以在UNNotificationResponse中获取
      10. NotificationViewController,App添加Notification Content Extension扩展的时候,自动生成的Controller,可以定义通知UI的主题部分,由StoryBoard指定设计
      11. UNNotificationContentExtension<协议>,NotificationViewController实现该协议,可以获得iOS展示自定义UI时候分发的UNNotification对象和用户交互的Response

本地通知

  1. 设置通知内容
    1. 创建通知内容对象
    2. 设置属性
    3. 设置通知的附件:视频/音频/图片/gif
    4. 设置互交类型
  2. 设置通知触发机制
  3. 创建一个UNNotificationRequest类的实例
    1. 一定要为它设置identifier, 在后面的查找,更新, 删除通知,这个标识是可以用来区分这个通知与其他通知
    2. 如果另一个request具有和之前request相同的标识,不同的内容, 可以达到更新通知的目的
  4. request加到UNUserNotificationCenter, 并设置触发器,等待触发
  5. 代码举例如下:

     //推送本地通知://使用UNNotification本地通知
     -(void)sendLocalNotification{
         //1. 设置通知内容
         //需创建一个包含待通知内容的UNMutableNotificationContent对象,注意不是UNNotificationContent ,此对象为不可变对象。
         UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
         //通知主标题
         content.title = @"主标题";
         //通知子标题
         content.subtitle = @"子标题";
         //设置通知的内容
         content.body = @"这是通知的内容????????????????????????";
         //或者也可以这样创建:
         //content.title = [NSString localizedUserNotificationStringForKey:@"主标题" arguments:nil];
         //content.body= [NSString localizedUserNotificationStringForKey:@"Hello_message_body" arguments:nil];
         //设置应用程序图标右上角的数字
         content.badge = @0;
         //设置有通知时的音效
         UNNotificationSound *sound = [UNNotificationSound defaultSound];
         content.sound = sound;
            
         //设置通知的附件:通知右边的图片
         //将本地图片的路径形成一个图片附件,加入到content中
         //视频
         //NSString *path = [[NSBundle mainBundle] pathForResource:@"flv视频测试用例1" ofType:@"mp4"];
         NSString *path = [[NSBundle mainBundle] pathForResource:@"beautiful" ofType:@"png"];
         NSError *error = nil;
         UNNotificationAttachment *img_attachment = [UNNotificationAttachment attachmentWithIdentifier:@"att1" URL:[NSURL fileURLWithPath:path] options:nil error:&error];
         content.attachments = @[img_attachment];
            
         //设置为@""以后,进入app将没有启动页
         content.launchImageName = @"";
            
         //通知的互交类型,Identifier可不是乱写的而是,在注册通知时设置好的
         content.categoryIdentifier = @"seeCategory1";
         //设置额外信息(比如:告诉app点击通知时跳转到哪一个界面)
         content.userInfo = @{@"type" : @1 };
            
         //2. 设置通知触发机制
         //通知触发机制
         //UserNotifications提供了三种触发器:
         //UNTimeIntervalNotificationTrigger:一定时间后触发(若重复提醒,时间间隔要大于60s)
         //UNCalendarNotificationTrigger:在某月某日某时触发
         //UNLocationNotificationTrigger:在用户进入或是离开某个区域时触发
         //UNPushNotificationTrigger: 远程推送
         //设置通知发出的时间
         UNTimeIntervalNotificationTrigger *time_trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
            
         //3.创建通知请求
         //创建UNNotificationRequest通知请求对象//创建一个发送请求
         //通知请求标识,便于管理该通知
         NSString *requestIdentifer = @"time interval request";
         UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:time_trigger];
            
         //4.将通知请求添加到通知中心
         [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {}];
     }
    
    
  6. 根据上面内容,大家会发现在创建UNNotificationRequest的时候,会需要UNMutableNotificationContent以及UNTimeIntervalNotificationTrigger这两个类。下面我就对相关的类,以及类扩展,做相应的说明

UNNotificationContent以及UNMutableNotificationContent(通知内容和可变通知内容)

  1. 通知内容分为可变的以及不可变的两种类型,类似于可变数组跟不可变数组。
  2. 后续我们通过某一特定标识符更新通知,便是用可变通知了。
  3. 不管是可变通知还是不可变通知,都有以下的几个属性:
    1. 附件数组,存放UNNotificationAttachment类

       @property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;
      
    2. 应用程序角标,0或者不传,意味着角标消失

       @property (NS_NONATOMIC_IOSONLY, copy, nullable) NSNumber *badge;
      
    3. 主体内容

       @property (NS_NONATOMIC_IOSONLY, copy) NSString *body ;
      
    4. 点击通知启动app时的图标
      1. 程序在后台时,此时程序没有杀死
      2. 设置任意字符串即可,只会显示启动图片的图标
       @property (NS_NONATOMIC_IOSONLY, copy) NSString *launchImageName;
      
    5. UNNotificationSound类,可以设置默认声音,或者指定名称的声音

       @property (NS_NONATOMIC_IOSONLY, copy, nullable) UNNotificationSound *sound ;
      
    6. 推送内容的子标题

       @property (NS_NONATOMIC_IOSONLY, copy) NSString *subtitle ;
      
    7. 通知线程的标识

       @property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier;
      
    8. 推送内容的标题

       @property (NS_NONATOMIC_IOSONLY, copy) NSString *title ;
      
    9. 远程通知附加的额外信息

       @property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *userInfo;
      
    10. 通知的互交类型
      1. Identifier可不是乱写的,而是在通知中心(UNUserNotificationCenter)在程序启动注册应用通知时给整个应用程序设置的所有互交类型,并且每个互交类型都有它的Identifier
      @property (NS_NONATOMIC_IOSONLY, copy) NSString *categoryIdentifier;
      

UNNotificationAttachment

  1. 在UNNotificationContent类中,有个附件数组的属性,这就是包含UNNotificationAttachment类的数组了。
  2. 苹果的解释说,UNNotificationAttachment(附件通知)是指可以包含音频,图像或视频内容,并且可以将其内容显示出来的通知。
  3. 使用本地通知时,可以在通知创建时,将附件加入即可。
  4. 对于远程通知,则必须实现使用UNNotificationServiceExtension类通知服务扩展。
  5. 创建附件的方法是

    + (nullable instancetype)attachmentWithIdentifier:(NSString *)identifier URL:(NSURL *)URL options:(nullable NSDictionary *)options error:(NSError *__nullable *__nullable)error;
    
    1. 在使用时,必须指定使用文件附件的内容,并且文件格式必须是支持的类型之一。
    2. 创建附件后,将其分配给内容对象的附件属性。
    3. 对于远程通知,您必须从您的服务扩展做到这一点。
  6. 附件通知支持的类型如下图:
    图1
  7. 注意:URL必须是一个有效的文件路径,不然会报错
  8. options参数是一个字典,但是其key实枚举,如下;
    1. UNNotificationAttachmentOptionsTypeHintKey:
      1. 此键的值(value)是一个描述文件类型的统一类型标识符(UTI)一个NSString。
      2. 如果不提供该键,附件的文件扩展名来确定其类型
      3. 常用的类型标识符有:kUTTypeImage,kUTTypeJPEG2000,kUTTypeTIFF,kUTTypePICT,kUTTypeGIF ,kUTTypePNG,kUTTypeQuickTimeImage等。
      4. 使用这些标识符之前要导入#import<MobileCoreServices/MobileCoreServices.h>框架
      5. 使用方法如下:

         dict[UNNotificationAttachmentOptionsTypeHintKey] = (__bridge id _Nullable)(kUTTypeImage);
        
    2. UNNotificationAttachmentOptionsThumbnailHiddenKey:
      1. 是一个BOOL值,为YES时候,缩略图将隐藏(即通知中(右中)带的图片),默认为NO。
      2. 使用方法如下:

          dict[UNNotificationAttachmentOptionsThumbnailHiddenKey] =  @YES;
        
    3. UNNotificationAttachmentOptionsThumbnailClippingRectKey
      1. 剪贴矩形的缩略图。
      2. 使用方法;

         dict[UNNotificationAttachmentOptionsThumbnailClippingRectKey] = (__bridge id _Nullable)((CGRectCreateDictionaryRepresentation(CGRectMake(0.5, 0.5, 0.25 ,0.25))));
        
      3. (0.5, 0.5, 0.25 ,0.25)这句话的意思是,以原缩略图左上角为原点截取一个x坐标为:0.5*长度,y坐标为:0.5*宽度,宽度为:0.25*宽度,长度为:0.25*长度的矩形图片作为新的缩略图(即通知右中的图片).
    4. UNNotificationAttachmentOptionsThumbnailTimeKey
      1. 一般影片附件会用到,指的是用影片中的某一秒来做这个缩略图;
      2. 使用方法如下:

        dict[UNNotificationAttachmentOptionsThumbnailTimeKey] =@10;
        
      3. 这里我们可以直接传递一个NSNumber的数值,比如使用影片第10s的画面来做缩略图就按照上面的来写。此外,要注意的是,这个秒数必须是这个影片长度范围内的,不然报错。

UNTimeIntervalNotificationTrigger

  1. UNPushNotificationTrigger
    1. (远程通知触发)一般我们不会使用的
  2. UNTimeIntervalNotificationTrigger
    1. (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。
    2. 使用方法:

       UNTimeIntervalNotificationTrigger *triggerOne = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
      
    3. 解释:上面的方法是指5秒钟之后执行。repeats这个属性,如果需要为重复执行的,则TimeInterval必须大于60s,否则会报: ` Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘time interval must be at least 60 if repeating’`的错误!
  3. UNCalendarNotificationTrigger
    1. (本地通知) 一定日期之后,重复或者不重复推送通知
    2. 例如,你每天8点推送一个通知,只需要dateComponents为8。如果你想每天8点都推送这个通知,只要repeats为YES就可以了。
    3. 代码举例:

       // 周一早上 8:00 上班
       NSDateComponents *components = [[NSDateComponents alloc] init];
       // 注意,weekday是从周日开始的,如果想设置为从周一开始,大家可以自己想想~
       components.weekday = 2;
       components.hour = 8;
       UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
      
    4. UNLocationNotificationTrigger
      1. (本地通知)地理位置的一种通知,使用这个通知,你需要导入
      2. #import<CoreLocation/CoreLocation.h>这个系统类库。示例代码如下:

         //1、如果用户进入或者走出某个区域会调用下面两个方法
         - (void)locationManager:(CLLocationManager *)manager
             didEnterRegion:(CLRegion *)region
         - (void)locationManager:(CLLocationManager *)manager
             didExitRegion:(CLRegion *)region代理方法反馈相关信息
                    
         //2、一到某个经纬度就通知,判断包含某一点么
         // 不建议使用!!!!!!CLRegion *region = [[CLRegion alloc] init];// 不建议使用!!!!!!
                    
                    
         CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] init];
         [circlarRegin containsCoordinate:(CLLocationCoordinate2D)];
                    
         UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:NO];
        
        
      3. 注意,这里建议使用CLCircularRegion这个继承自CLRegion的类,因为我看到苹果已经废弃了CLRegion里面是否包含这一点的方法,并且推荐我们使用CLCircularRegion这个类型

点击通知(包含远程和本地)

  1. 第一步在Appdelegate.m中导入#import <UserNotifications/UserNotifications.h>
  2. 我们最好写成这种形式

     #ifdef NSFoundationVersionNumber_iOS_9_x_Max
     #import <UserNotifications/UserNotifications.h>
     #endif
    

didFinishLaunchingWithOptions的处理(包含本地和远程)

  1. 请求用户授权/注册远程通知
    1. 获取应用的通知管理中心UNUserNotificationCenter,来管理推送通知

        UNUserNotificationCenter* center = [UNUserNotificationCenter   currentNotificationCenter];
      
    2. 设置推送通知中心的代理,实现代理方法,监听通知的推送
      1. 注意:UNUserNotificationCenterdelegate必须在application:willFinishLaunchingWithOptions: or application:didFinishLaunchingWithOptions:方法中实现;

         center.delegate = self;
        
    3. 设置预设好的交互类型,NSSet里面是设置好的UNNotificationCategory
      1. 就是当接收到通知时,拖拽向下,会看到互交控件:是按钮点击/还是文本输入,不设置没有按钮
      2. 也就是本地通知中UNMutableNotificationContent类的categoryIdentifier属性要在这些设置好的互交类型中选择

          [center setNotificationCategories:[self createNotificationCategoryActions]];
        
    4. 请求用户授权

       //请求获取通知权限(角标,声音,弹框)
       [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
           if (granted) {
               //获取用户是否同意开启通知
               NSLog(@"request authorization successed!");
           }
       }];
      
    5. 注册远程通知(只用本地时不需要)
      1. 调用该方法就是向苹果的apns服务器发送该设备的udid和bundle id,返回deviceToken
      2. 如果获取不到deviceToken,Xcode8下要注意开启Capability->Push Notification。

          [application registerForRemoteNotifications];
        
  2. 交互类型的自定义方法
    1. iOS10通知上的交互只有两种,一种是Button一种是text,就算使用了iOS10 Notification Content Extension也不能添加自定义的按钮或者其他交互组件,因为不会响应。
    2. UNNotificationAction 在初始化的时候需要定义UNNotificationActionOptions,这个UNNotificationActionOptions的意思是:

       typedef NS_OPTIONS(NSUInteger, UNNotificationActionOptions) {
       
       // Whether this action should require unlocking before being performed.
       //指定该动作是否需要用户解锁验证身份
       UNNotificationActionOptionAuthenticationRequired = (1 << 0),
           
       // Whether this action should be indicated as destructive.
       //指定用户执行该动作是否要将通知从iOS的通知中心移除,以防止处理过该通知以后重复处理
       UNNotificationActionOptionDestructive = (1 << 1),
           
       // Whether this action should cause the application to launch in the foreground.
       //指定通知action点击后是否要进入app到前台,如果到前台,这个对Notification Content Extension的自定义的通知UI有意义,
       //可以在Extension中处理用户的点击或者提交文字,那么就可以指定该action不需要进入app,
       //UNNotificationActionOptionAuthenticationRequired这个就不要加入
       UNNotificationActionOptionForeground = (1 << 2),
       } __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
      
     -(NSSet *)createNotificationCategoryActions{
     //1.设置交互类型1:seeCategory 2个按钮
     //1.1 定义按钮的交互button action
     //Identifier:互交的标识,当用户点击时可以再用户点击方法中查看点击是哪个btn
     //title:标题
     UNNotificationAction * likeButton = [UNNotificationAction actionWithIdentifier:@"see1" title:@"看一看" options:UNNotificationActionOptionAuthenticationRequired|UNNotificationActionOptionDestructive|UNNotificationActionOptionForeground];
     UNNotificationAction * dislikeButton = [UNNotificationAction actionWithIdentifier:@"see2" title:@"忽略" options:UNNotificationActionOptionAuthenticationRequired|UNNotificationActionOptionDestructive|UNNotificationActionOptionForeground];
     //1.2 将这些action带入category
     //Identifier:创建通知时会使用到这个,根据这个查看到底选择哪种互交方式
     UNNotificationCategory * choseCategory = [UNNotificationCategory categoryWithIdentifier:@"seeCategory" actions:@[likeButton,dislikeButton] intentIdentifiers:@[@"see1",@"see2"] options:UNNotificationCategoryOptionNone];
        
     //2. 设置交互类型2:seeCategory1  文本框输入类型
     //2.1 创建textAction
     UNTextInputNotificationAction * text = [UNTextInputNotificationAction actionWithIdentifier:@"text" title:@"回复" options:UNNotificationActionOptionAuthenticationRequired|UNNotificationActionOptionDestructive|UNNotificationActionOptionForeground];
     //2.2 将action加入UNNotificationCategory
     UNNotificationCategory * comment = [UNNotificationCategory categoryWithIdentifier:@"seeCategory1" actions:@[text] intentIdentifiers:@[@"text"] options:UNNotificationCategoryOptionNone];
        
     //3. 将交互类型插入NSSet中,然后给整个app应用设置
     return [NSSet setWithObjects:choseCategory,comment,nil];
     }
    
  3. 监听deviceToken的获取(远程通知使用)
    1. 获得Device Token的方法是没有改变的。

       // 监听苹果返回devicetoken
       -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
           //4.将DeviceToken传给服务器
           NSLog(@"%@", deviceToken.description);
       }
       //向apns请求失败
       -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
           NSLog(@"===请求devicetoken失败==%@",error);
       }
      
  4. UNUserNotificationCenter的其他使用方法:
    1. 获取当前应用的通知设置
      1. UNNotificationSettings是只读对象,不能直接修改,只能通过以下方法获取
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
              
       // UNAuthorizationStatus NotDetermined :没有做出选择
       // UNAuthorizationStatus Denied :用户未授权
       // UNAuthorizationStatus Authorized:用户已授权
       //进行判断做出相应的处理
       if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined)
       {
           NSLog(@"未选择");
       }else if (settings.authorizationStatus ==     UNAuthorizationStatusDenied){
           NSLog(@"未授权");
       }else if (settings.authorizationStatus ==    UNAuthorizationStatusAuthorized){
           NSLog(@"已授权");
       }
       }];
      
    2. 获取到当前用户推送中心所有设置的互交类型

       [center getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> * _Nonnull categories) {
              
       }];
      
    3. 常见的通知操作

        //拿到通知中心
       UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];//①
       //-移除还未展示的通知
       [center removePendingNotificationRequestsWithIdentifiers: @[@"RequestIdentifier"]];
       //移除所有未展示的通知
       [center removeAllPendingNotificationRequests]; //- (void)cancelAllLocalNotifications;
              
       //-移除已经展示过的通知
       //这里的Identifiers就是你创建通知时设置的,便于管理改通知
       [center removeDeliveredNotificationsWithIdentifiers:@[@"RequestIdentifier"]];
       [center removeAllDeliveredNotifications];
              
       //-获取未展示的通知请求
       [center getPendingNotificationRequestsWithCompletionHandler:^(NSArray * _Nonnull requests) {
           NSLog(@"%@",requests);
       }];
              
       //-获取展示过的通知
       [center getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) {
           NSLog(@"%@",notifications);
       }];
      

推动通知的监听

  1. 此次iOS10系统的更新,苹果给了我们2个代理方法来处理通知的接收和点击事件,这两个方法在<UNUserNotificationCenterDelegate>的协议中
  2. 苹果把本地通知跟远程通知合二为一
  3. 区分本地通知跟远程通知的类是UNPushNotificationTrigger

代理方法1:

  1. 调用时刻:
    1. 应用程序在前台台时调用(通知即将展示,还没有展示时),即不点击通知就会调用
    2. 程序处于后台/杀死状态时都不会调用
  2. 作用:
    1. 在展示通知前进行处理,即有机会在展示通知前再修改通知内容。
    2. 如果你的App在前台,一般在这个回调函数里做一些数据加解密、数据下载,然后将下载的数据组装成UNNotificationAttachment或者是根据通知里面的content里面的userinfo里与后端服务约定好的修改通知对应的categoryId,调用相应的交互组件到通知上,completionHandler在你想要做的逻辑完成以后调用。
    3. 如果App在前台,你接收到通知,不想显示系统提示框,想使用App 自定义的通知消息弹窗,可以在completionHandler回调的时候传入的opinion不要带上UNAuthorizationOptionAlert,然后直接弹自定义的弹窗就Ok。
  3. 特点:
    1. 如果该方法没有实现或者没有回调用completionHandler则前台通知将不会呈现,也接收不到
  4. 应用程序可以通过completionHandler()回调,选择怎样呈现这个通知: 只有角标变化的通知/只有声音提示/只有弹框提示或者3种的组合
  5. 代码如下:

     -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
     // 原始请求
     UNNotificationRequest *request = notification.request;
     // 获取请求的额外信息
     NSDictionary * userInfo = notification.request.content.userInfo;//userInfo数据
     // 请求的内容
     UNNotificationContent *content = request.content; // 原始内容
     NSString *title = content.title;  // 标题
     NSString *subtitle = content.subtitle;  // 副标题
     NSNumber *badge = content.badge;  // 角标
     NSString *body = content.body;    // 推送消息体
     UNNotificationSound *sound = content.sound;  // 指定的声音
     //本地通知的判断:notification.request.trigger类型判断是远程还是本地推送
     if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
         NSLog(@"iOS10代理方法一的远程通知:%@",[notification description]);
            
     }else{
         NSLog(@"iOS10代理方法一的本地通知:%@",[notification description]);
     }
     //设置怎样接收通知:只有角标变化的通知/只有声音提示/只有弹框提示/3中的组合
     completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
     }
    

代理方法二:

  1. 调用时刻
    1. 应用程序在后台/杀死状态下都会调用
    2. 用户点击通知打开app
    3. 下拉通知,选择一个互交动作:点击互交按钮/文本输入后点击发送
    4. 跟后台发送content-available没任何关系,必须操作才会调用
  2. 作用:
    1. 点击通知处理通知内容
  3. 该回调函数仅仅用来处理数据和重新选择交互方式,其他远程推送到达设备要做的业务逻辑
  4. 如果不写completionHandler()这个方法,会报错误
  5. 代码举例:

     -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
        
     //1.获取到通知详情
     UNNotificationRequest *request = response.notification.request; // 原始请求
     NSDictionary * userInfo = request.content.userInfo;//userInfo数据
     UNNotificationContent *content = request.content; // 原始内容
     //2.判断通知的种类
     if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
         NSLog(@"代理方法二的远程通知");
     }else{
         NSLog(@"代理方法二的本地通知");
     }
        
     //3.根据response的种类判断用户的互交类型
     //可根据actionIdentifier来做业务逻辑
     if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) {
         //交互类型为文本输入
         UNTextInputNotificationResponse * textResponse = (UNTextInputNotificationResponse*)response;
         //拿到用户交互的内容
         NSLog(@"用户输入的内容为: %@",textResponse.userText);
     }else{ //交互类型为点击按钮
         //点击第一个交互按钮
         if ([response.actionIdentifier isEqualToString:@"see1"]) {
             //看一看的处理
             NSLog(@"用户点击的按钮为see1");
         }
         //点击第二个交互按钮
         if ([response.actionIdentifier isEqualToString:@"see2"]) {
             //删除已经推动过的推送需求
             NSLog(@"用户点击的按钮为see2");
             //忽略的处理
             [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[response.notification.request.identifier]];
         }
     }
     completionHandler();
     }
    
Table of Contents