iOS 通知扩展插件

  • Notification Content Extension

    • 通知内容扩展,是在展示通知时展示一个自定义的用户界面。
  • Notification Service Extension

    • 通知服务扩展,是在收到通知后,展示通知前,做一些事情的。比如,增加附件,网络请求等。

Notification Service Extension

  • 目前只找到aps推送支持
  • 主要是处理一下附件相关的下载

新建一个target

  • 老的xcode版本开启VoIP功能也是在 Background Modes 中直接勾选就开启了,但是新版的xcode移除了这个选项,所以只能在 info.plist 文件中去手动添加
  • 参考1
  • 参考2

代码实现

  1. @interface NotificationService : UNNotificationServiceExtension
  2. @end

  1. #import "NotificationService.h"
  2. #import <UIKit/UIKit.h>
  3. @interface NotificationService ()
  4. @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
  5. @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
  6. @end
  7. @implementation NotificationService
  8. // 系统接到通知后,有最多30秒在这里重写通知内容(在此方法可进行一些网络请求,如上报是否收到通知等操作)
  9. - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  10. NSLog(@"%s",__FUNCTION__);
  11. self.contentHandler = contentHandler;
  12. self.bestAttemptContent = [request.content mutableCopy];
  13. // Modify the notification content here...
  14. NSLog(@"%@",request.content);
  15. // 添加附件
  16. //1. 下载
  17. NSURL *url = [NSURL URLWithString:@"https://tva1.sinaimg.cn/large/008i3skNgy1gtir9lwnj0j61x40gsabl02.jpg"];
  18. NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
  19. NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
  20. NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  21. if (!error) {
  22. //2. 保存数据
  23. NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject
  24. stringByAppendingPathComponent:@"download/image.jpg"];
  25. UIImage *image = [UIImage imageWithData:data];
  26. NSError *err = nil;
  27. [UIImageJPEGRepresentation(image, 1) writeToFile:path options:NSAtomicWrite error:&err];
  28. //3. 添加附件
  29. UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"remote-atta1" URL:[NSURL fileURLWithPath:path] options:nil error:&err];
  30. if (attachment) {
  31. self.bestAttemptContent.attachments = @[attachment];
  32. }
  33. }else{
  34. self.bestAttemptContent.title = @"标题";
  35. self.bestAttemptContent.subtitle = @"子标题";
  36. self.bestAttemptContent.body = @"body";
  37. }
  38. //4. 返回新的通知内容
  39. self.contentHandler(self.bestAttemptContent);
  40. }];
  41. [task resume];
  42. }
  43. // 处理过程超时,则收到的通知直接展示出来
  44. - (void)serviceExtensionTimeWillExpire {
  45. NSLog(@"%s",__FUNCTION__);
  46. self.contentHandler(self.bestAttemptContent);
  47. }
  48. @end

注意事项

  • UNNotificationAttachment:attachment 支持

    • 音频 5M(kUTTypeWaveformAudio/kUTTypeMP3/kUTTypeMPEG4Audio/kUTTypeAudioInterchangeFileFormat)
    • 图片10M(kUTTypeJPEG/kUTTypeGIF/kUTTypePNG)
    • 视频50M(kUTTypeMPEG/kUTTypeMPEG2Video/kUTTypeMPEG4/kUTTypeAVIMovie)

UINotificationConentExtension

配置项目

  • 新建target,打开推送服务

配置info.plist

  • 配置info.plist,和Notification Service Extension进行关联

  • 找到这个 UNNotificationExtensionCategory,写到Notification Service Extension中,可以配置多个,对应多个界面
  1. self.bestAttemptContent.categoryIdentifier = @"myNotificationCategory";// 和NotificationConentExtension关联
  2. self.contentHandler(self.bestAttemptContent);

自定义UI

  • 如果我们想要隐藏系统默认的内容页面,也就是下面的那部分,头是隐藏不了的;只需要在Info.plist里添加字段UNNotificationExtensionDefaultContentHidden,bool类型并设置其值为YES;

  • 可以直接修改stroryboard

  • 添加Action,可以添加基本的事件


  1. #import "NotificationViewController.h"
  2. #import <UserNotifications/UserNotifications.h>
  3. #import <UserNotificationsUI/UserNotificationsUI.h>
  4. @interface NotificationViewController () <UNNotificationContentExtension,UIActionSheetDelegate>
  5. @property IBOutlet UILabel *label;
  6. @property (weak, nonatomic) IBOutlet UIImageView *imageView;
  7. @end
  8. @implementation NotificationViewController
  9. - (void)viewDidLoad {
  10. [super viewDidLoad];
  11. NSLog(@"%s",__FUNCTION__);
  12. // 添加action
  13. UNNotificationAction * likeAction; //喜欢
  14. UNNotificationAction * ingnoreAction; //取消
  15. UNTextInputNotificationAction * inputAction; //文本输入
  16. likeAction = [UNNotificationAction actionWithIdentifier:@"action_like" title:@"点赞"
  17. options:UNNotificationActionOptionForeground];
  18. inputAction = [UNTextInputNotificationAction actionWithIdentifier:@"action_input"title:@"评论"
  19. options:UNNotificationActionOptionForeground textInputButtonTitle:@"发送"textInputPlaceholder:@"说点什么"];
  20. ingnoreAction = [UNNotificationAction actionWithIdentifier:@"action_cancel"title:@"忽略" options:UNNotificationActionOptionDestructive];
  21. NSString *categoryWithIdentifier = @"myNotificationCategory";// 和info.plist中配置的id一样
  22. UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:categoryWithIdentifier actions:@[likeAction,inputAction,ingnoreAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
  23. NSSet *sets = [NSSet setWithObjects:category,nil];
  24. [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:sets];
  25. }
  26. - (void)didReceiveNotification:(UNNotification *)notification {
  27. self.label.text = notification.request.content.body;
  28. NSLog(@"didReceiveNotification:%@",notification.request.content);
  29. for (UNNotificationAttachment * attachment in notification.request.content.attachments) {
  30. NSLog(@"url:%@",attachment.URL);
  31. // 显示图片
  32. if([attachment.URL startAccessingSecurityScopedResource]){
  33. NSData *data = [NSData dataWithContentsOfURL:attachment.URL];
  34. self.imageView.image = [UIImage imageWithData:data];
  35. [attachment.URL stopAccessingSecurityScopedResource];
  36. }
  37. }
  38. }
  39. - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion {
  40. NSLog(@"response:%@",response);
  41. if ([response.actionIdentifier isEqualToString:@"action_like"]) {
  42. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  43. completion(UNNotificationContentExtensionResponseOptionDismiss);
  44. });
  45. } else if ([response.actionIdentifier isEqualToString:@"action_input"]) {
  46. UNTextInputNotificationResponse *inputAction = (UNTextInputNotificationResponse*)response;
  47. NSLog(@"输入内容:%@",inputAction.userText);
  48. // TODO: 发送评论
  49. completion(UNNotificationContentExtensionResponseOptionDismiss);
  50. } else if ([response.actionIdentifier isEqualToString:@"action_cancel"]) {
  51. completion(UNNotificationContentExtensionResponseOptionDismiss);
  52. } else {
  53. completion(UNNotificationContentExtensionResponseOptionDismiss);
  54. }
  55. completion(UNNotificationContentExtensionResponseOptionDoNotDismiss);
  56. }
  57. @end
  • info.plist

  • aps 格式
  1. {
  2. "aps":
  3. {
  4. "alert":
  5. {
  6. "title":"iOS10远程推送标题",
  7. "subtitle" : "iOS10 远程推送副标题",
  8. "body":"这是在iOS10以上版本的推送内容,并且携带来一个图片附件"
  9. },
  10. "badge":1,
  11. "mutable-content":1,
  12. "media":"image",
  13. "image-url":"https://tva1.sinaimg.cn/large/008i3skNgy1gtmd6b4whhj60fq0g6tb502.jpg"
  14. }
  15. }

iOS 通知扩展插件的更多相关文章

  1. 使用 Swift 制作一个新闻通知中心插件(1)

    input[type="date"].form-control,.input-group-sm>input[type="date"].input-grou ...

  2. Swift 制作一个新闻通知中心插件1

    使用 Swift 制作一个新闻通知中心插件(1) 随着 iOS 8 的发布,苹果为开发者们开放了很多新的 API,而在这些开放的接口中 通知中心插件 无疑是最显眼的一个.通知中心就不用过多介绍了,相信 ...

  3. 使用 Swift 制作一个新闻通知中心插件(2)

    我们在第一部分的文章中详细讲解了创建一个通知中心插件的整体过程.我们成功的在通知中心里面显示了新闻列表.但是截止到目前,我们还不能从通知中心的列表中查看新闻的详细内容.在这次的教程中,我们就以上次的教 ...

  4. 100个精选zencart扩展插件

    100个精选zencart扩展插件 特别推荐 1. 数据库备份 2. 产品横向布局. 3. 邮件订阅Newsletter Subscribe. 4. google 翻译google_translate ...

  5. jupyter notebook设置主题背景,字体和扩展插件

    windows上安装Anaconda (IPython notebook) Anaconda是一个包与环境的管理器,一个Python发行版,以及一个超过1000多个开源包的集合.它是免费和易于安装的, ...

  6. 认识Chrome扩展插件

    1.前言 现如今的时代,绝大多数人都要跟浏览器打交道的,说到浏览器那肯定是Chrome浏览器一家独大,具体数据请看 知名流量监测机构 Statcounter 公布了 7 月份全球桌面浏览器市场份额,主 ...

  7. 提高工作效率的神器:基于前端表格实现Chrome Excel扩展插件

    Chrome插件,官方名称extensions(扩展程序):为了方便理解,以下都称为插件. 我们开发的插件需要在浏览器里面运行,打开浏览器,通过右上角的三个点(自定义及控制)-更多工具-拓展程序-打开 ...

  8. iOS通知的整理笔记

    iOS通知用于高耦合界面的传值确实方便快捷. 需要实现模态弹出的视图控制器上,有一个视图控制器可以导航.这必定要将这个视图控制器的导航视图控制器naVC.view添加到模态弹出的视图控制器presen ...

  9. BlazeMeter发布chrome扩展插件,支持JMeter脚本创建

    BlazeMeter发布chrome扩展插件,支持JMeter脚本创建http://www.automationqa.com/forum.php?mod=viewthread&tid=3898 ...

随机推荐

  1. 使用PostGIS完成两点间的河流轨迹及流经长度的计算

    基础准备工作 1.PostGIS 的安装 在安装PostGIS前首先必须安装PostgreSQL,然后再安装好的Stack Builder中选择安装PostGIS组件.具体安装步骤可参照 PostGI ...

  2. [CISCN2019 华东南赛区]Web11

    [CISCN2019 华东南赛区]Web11 写在前面 参考文章:Smarty SSTI 1.{php}{/php} Smarty已经废弃{php}标签,强烈建议不要使用.在Smarty 3.1,{p ...

  3. [C语言基础] 数组与指针之间的引用

    通过指针引用数组,通过数组引用指针,你搞明白了么?通过下面3种情形来了解一下数组和指针 Case 1. unsigned char arry[10]; unsigned char *ptr; unsi ...

  4. c#重写和多态

    多态是基于重写的 继承:向子类中添加父类没有的成员,子类对父类的横向扩展 重写:纵向扩展,成员没有增加,但成员的版本增加了 引言 Rider JetBrains:Rider.ReSharper.dot ...

  5. 学习AJAX必知必会(4)~同源策略、解决跨域问题(JSONP、CORS)

    一.同源策略(Same-Origin Policy),是浏览器的一种安全策略. 1.同源(即url相同):协议.域名.端口号 必须完全相同.(请求是来自同一个服务) 2.跨域:违背了同源策略,即跨域. ...

  6. lua之自索引

    Father={ a=100, b=200 } function Father:dis() print(self.a,self.b) end Father.__index=Father Son= { ...

  7. C++构造函数语义学(二)(基于C++对象模型)

    带有虚函数的情况. 下面情况编译器也会在需要的时候为其合成. 1.如果一个类自己声明为虚函数. 1 #include<iostream> 2 using namespace std; 3 ...

  8. 集合框架-ArrayList集合存储自定义对象

    1 package cn.itcast.p3.arraylist.test; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; ...

  9. Java 将PDF转为HTML时保存到流

    本文介绍如何通过Java后端程序代码将PDF文件转为HTML,并将转换后的HTML文件保存到流.在实现转换时,可设置相关转换属性,如:是否嵌入SVG.是否嵌入图片等.下面是实现转换的方法和步骤: 1. ...

  10. HTML(前端web)

    目录 一:HTML前端 1.什么是前端? 2.什么是后端? 3.什么是HTML? 4.HTML不是什么? 5.前端的学习流程 6.BS架构 7.搭建服务器 简易(浏览器访问) 8.浏览器访问报错原因 ...