美文网首页iOS进阶iOS技术分享UI进价
玩转 iOS 10 推送 —— UserNotification

玩转 iOS 10 推送 —— UserNotification

作者: pikacode | 来源:发表于2016-09-21 17:37 被阅读13178次

上一篇 咱们聊了一些:

  • iOS 10 before 推送的流程
  • iOS 10 beta 推送的基本使用方法
  • 以及跟 iOS 10 before 推送的区别

这一篇咱们将继续探讨 iOS 10 推送,并向大家介绍一些进阶的内容。

Notification Actions

在 iOS 10 中,可以允许推送添加交互操作 action,这些 action 可以使得 App 在前台或后台执行一些逻辑代码。并且在锁屏界面通过 3d-touch 触发。如:推出键盘进行快捷回复,该功能以往只在 iMessage 中可行。
(Notification Actions 在 iOS 8 引入,快捷回复在 iOS 9 引入,在 iOS 10 中,这些 API 被统一。)

在 iOS 10 中,这叫 category,是对推送功能的一个拓展,可以通过 3d-touch 触发。

  1. 创建 action

    • 即一项交互操作

    • title 是交互按钮的内容

    • options 可以让该 action 成为一条可在前台执行的 action

    • 创建:

      UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:@"reply" title:@"Reply" options:UNNotificationActionOptionNone];
      
  2. 创建 category

    • 可添加多个 action 的数组,就像图片中一样,有多种操作

    • 其中的 id,需要填写你想要添加到哪个推送消息的 id

    • 创建:

      UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"message" actions:@[action] minimalActions:@[action] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
      
  3. category 添加到通知中心:

[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithArray:@[category]]];


4. 触发方式:

- Remote Notifications 配置 payload,指定其中 category 的值与第 2 步中 Identifier 一致:

  ```objc
  {
    aps : {
    alert : "Welcome to WWDC !",
    category : "message"
         }
  }
  ```

- Local Notifications 只需要在创建 contnet 的时候指定 Id 即可:(content 相关内容请参照 [上一篇](http://www.jianshu.com/p/2f3202b5e758) 中的 Content 部分)

  ```objc
  content。categoryIdentifier = @"message";
  ```

  ​

#### Dismiss Actions

锁屏及在通知中心收到推送,侧滑,会展示 action。

只要点击 Clear 就可以将该条推送清除,并且重复的内容不会被发送到你的其他 iOS 设备上。

![](http:https://img.haomeiwen.com/i1944178/3ebc9b53bcf6dc5c.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i1944178/68b7a8edd4ff5d27.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

跟 Notification Actions 只有一点小区别,就是添加 action 到 category 的时候,增加一个 option 的值 UNNotificationCategoryOptionCustomDismissAction:

```objc
UNNotificationAction *clearAction = [UNNotificationAction actionWithIdentifier:@"clear" title:@"clear" options:UNNotificationActionOptionNone];

UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"clear" actions:@[clearAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];//这里增加一个 dismiss 的值

Response handling

用户点击这些 actions 以后,是启动 App、触发键盘、清除通知或是有其他的响应,这些全部只需要实现协议 UNUserNotificationCenterDelegate 中的一个方法就可以控制:

@interface ClassName () <UNUserNotificationCenterDelegate>
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{

}

其中的 response 包含以下内容:

其中的 trigger 可以用来判断是远程推送还是本地推送。

处理 response 举例:

-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{

    NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;

    if ([categoryIdentifier isEqualToString:@"handle category"]) {//识别需要被处理的拓展

        if ([response.actionIdentifier isEqualToString:@"input text"]) {//识别用户点击的是哪个 action

            //假设点击了输入内容的 UNTextInputNotificationAction 把 response 强转类型
            UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse*)response;
            //获取输入内容
            NSString *userText = textResponse.userText;
            //发送 userText 给需要接收的方法
            [ClassName handleUserText: userText];
        }else{

        }

    }
    completionHandler();
}

Service Extension


可以在手机「接收到推送之后、展示推送之前」对推送进行处理,更改、替换原有的内容。

使用了这个玩意,你们公司原有发送推送的 payload 可以完全不变,而在客户端对接收到的内容(只有一条字符串)进行加工,从而适配 iOS 10 的展示效果(标题+副标题+内容)。

「接收到推送之后、展示推送之前」:
  • 此时,你获得了一小段在后台运行代码的时间(也可以用来干别的坏事>。<,可以偷偷的断点下载你们 App 的更新包)
  • 而如果你更改推送内容出了错误,或者你调用什么方法失败了,那么最终会正常的展示最初接收到的推送内容。

Potential uses

值得你们 App 充分发挥的是可以做以下事情:

  • 端到端加密
  • 给推送展示内容添加附件(比如照片、背景音乐),使得内容更加丰富,就像从推送里拉出了一个网页有木有!

不急,我们先来介绍怎么

添加 Service Extension

先在 Xcode 打开你的 App 工程,File - New - Target 然后添加这个:

然后会自动创建一个 UNNotificationServiceExtension 的子类 NotificationService,通过完善这个子类,来实现你的需求。

点开 NotificationService.m 会看到 2 个方法:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
    
    self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
    self.contentHandler(self.bestAttemptContent);
}
  • didReceiveNotificationRequest 让你可以在后台处理接收到的推送,传递最终的内容给 contentHandler
  • serviceExtensionTimeWillExpire 在你获得的一小段运行代码的时间即将结束的时候,如果仍然没有成功的传入内容,会走到这个方法,可以在这里传肯定不会出错的内容,或者他会默认传递原始的推送内容
Example payload
{
  aps : {
    alert : "New Message",
    mutable-content : 1
  },
  encrypted-content : "#myencryptedcontent"
}

首先需要添加 mutable-content : 1,这意味着此条推送可以被 Service Extension 进行更改

同时可以附加一条 encrypted-content,可以提取该内容进行替换

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {

    //用你的重编码方法对该内容进行更改
    NSString *decryptedBody = [DecryptClass decrypt: request.content.userInfo[@"encrypted-content"]];

    //创建新的 content 并添加修改过的 body
    UNMutableNotificationContent *newContent = [UNMutableNotificationContent new];

    newContent.body = decryptedBody;

    //回调新的 content
    contentHandler(newContent);
}

继续浏览 《玩转 下》

相关文章

网友评论

  • coder小鹏:我创建了notification service extension ,但是里面的方法打断点不执行,楼主遇到过吗???
  • 男儿心:你好,我创建了notification service extension ,但是里面的方法打断点不执行,为何呢,我的 mutable-content : 1 这个内容是在aps 外部加的,有影响吗?
    男儿心:@pikacode 啥意思?
    pikacode:target
  • L晨曦:请问一下我程序杀死后,怎么获取快速回复的输入内容 ?
  • kongkk:楼主,我问个问题呀,关于Action添加到Cateogry中的option选择UNNotificationCategoryOptionCustomDismissAction,但是侧滑通知的时候还是只有查看和清除,这不正常呀?是什么原因呢?求解!!!
    kongkk:@pikacode 找到了345192153
    kongkk:@pikacode 我想说q群号在哪里呀?
    pikacode:@蜡泪再塑 加q群
  • 权欣权忆:有《玩转 iOS 10 推送 —— UserNotifications Framework(下)》了吗?
    pikacode:@权欣权忆 去年就有了
  • 琦均煞Sylar:UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"hello" title:@"你好" options:UNNotificationActionOptionNone];
    UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"world" title:@"世界" options:UNNotificationActionOptionNone];
    UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"recall" title:@"回拨" options:UNNotificationActionOptionNone];
    UNNotificationAction *action4 = [UNNotificationAction actionWithIdentifier:@"dream" title:@"梦想" options:UNNotificationActionOptionNone];
    ----------------------------------------------------------
    NSArray *actionArr = @[action2,action1,action4,action3];
    NSArray *idArray = @[action1.identifier,action2.identifier,action3.identifier,action4.identifier];
    -----------------------------------------------------------------------------
    UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"message" actions:actionArr intentIdentifiers:idArray options:UNNotificationCategoryOptionNone];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithArray:@[category]]];
    ----------------------------------------------
    这样才管用,你这里有一个方法失效了。
    另外,category中的 identifier数组,存放的是上面 action的identifier.
    此外。列表的顺序与action数组顺序直接相关,与identfifer数组书序无关
    -------------------------------------------------------------------------
    是否能贴出响应事件的处理部分呢
    pikacode:@琦均煞Sylar 手机qq
    琦均煞Sylar:@pikacode 该群主拒绝任何新成员加入该群
    pikacode:个人主页加Q群
  • f4f43026010c:点击replay 什么在哪里能拦截到处理方法呢,我要点击reply要做一些操作的
    pikacode:@Snail_JJ didresponse
    pikacode:什么?
  • 乐在琦中Helena:category的option不选择UNNotificationCategoryOptionCustomDismissAction而是使用默认的UNNotificationCategoryOptionNone也是可以通过侧滑显示action详情的,UNNotificationCategoryOptionCustomDismissAction这个选项应该还有别的作用吧
    pika11:我同意提问者的看法。它的其他作用就是触发代理方法,如果是UNNotificationCategoryOptionNone不会触发didReceiveNotificationResponse方法。
    pikacode:@乐在琦中Helena 这个是忽略。按了就是啥都不发生。response 里收到的结果就是 dismiss。比如邮件操作,可以有删除、忽略(不会看)、暂不操作(none,有空会看),标记等等。
  • f6807b908a23:您好 我在创建了ServiceExtention之后 编译出现这个错误 NBPushServiceEx has conflicting provisioning settings. NBPushServiceEx is automatically signed, but code signing identity iPhone Developer:这里是我证书的名字 has been manually specified. Set the code signing identity value to "iPhone Developer" in the build settings editor, or switch to manual signing in the project editor.
    Code signing is required for product type 'App Extension' in SDK 'iOS 10.0'
    意思是不能用这个证书吗?
    f6807b908a23:@七_七 这方面没怎么接触过 不是太明白
    f6807b908a23:@pikacode 大概意思我知道 我不懂为什么会出现这个问题 是让我换个证书?
    pikacode:@七_七 谷歌翻译
  • chouson_chan:UNTextInputNotificationResponse * textResponse = (UNTextInputNotificationResponse *)response;
    这样子强转后不行了,程序crash了
    报如下错误:
    [UNNotificationResponse userText]: unrecognized selector sent to instance 0x6000002232c0'

    强转失败,求解大神 :joy:
    pikacode:@chouson_chan :smile:
    chouson_chan:@chouson_chan 解决了, 原来action也要改为相关类UNTextInputNotificationAction
  • _烩面_:在创建了notification service extension之后 用主工程的证书不行 要单独配个证书吗?
    pikacode:@jian00 不用的
  • 小北风sky:把你头像偷走没意见吧。。 :flushed:
    Bug猫:没忍住,也偷了 :joy:
    小北风sky:@pikacode 哈哈,感谢分享:joy::v:️️
    pikacode:@小北风sky 被偷好多次啦>_<
  • 1347d391f7db:好详细,帮助很大,期待(下)!
  • Dismon:创建notification service extension 之后, 收到通知,明没有改变通知的内容,didReceiveNotificationRequest,中的代码就是创建之后的代码,没动,payload 里面已经添加了mutable-content : 1 请问大神是什么原因
    pikacode:@Dismon 需要切换 target 运行
    Dismon:@pikacode 是的,我是创建notification service extension 之后没有改代码,自带的didReceiveNotificationRequest 如果执行的话,title会改变。 我试了运行的notification service extension这target,选择依赖的app, 活着直接运行app 都不会进入didReceiveNotificationRequest 代码,是不是我service 用的不对呢
    pikacode:service里的方法能不能执行?
  • Bc_wh1te_Le1:Response handling 处理response回调不执行 deledelegate已添加
  • o0下一站生活0o:群主继续。看了那么多关心IOS10推送的文字,只有群主的最牛逼!
    pikacode:你们也挺牛逼的

本文标题:玩转 iOS 10 推送 —— UserNotification

本文链接:https://www.haomeiwen.com/subject/utcljttx.html