iOS|iOS 通知扩展插件

iOS 通知扩展插件
目录

  • iOS 通知扩展插件
    • Notification Service Extension
      • 新建一个target
      • 代码实现
      • 注意事项
    • UINotificationConentExtension
      • 配置项目
      • 配置info.plist
      • 自定义UI
【iOS|iOS 通知扩展插件】
  • Notification Content Extension
    • 通知内容扩展,是在展示通知时展示一个自定义的用户界面。
  • Notification Service Extension
    • 通知服务扩展,是在收到通知后,展示通知前,做一些事情的。比如,增加附件,网络请求等。
Notification Service Extension
  • 目前只找到aps推送支持
  • 主要是处理一下附件相关的下载
新建一个target
  • 老的xcode版本开启VoIP功能也是在 Background Modes 中直接勾选就开启了,但是新版的xcode移除了这个选项,所以只能在 info.plist 文件中去手动添加
  • 参考1
  • 参考2
iOS|iOS 通知扩展插件
文章图片

代码实现
@interface NotificationService : UNNotificationServiceExtension@end

#import "NotificationService.h" #import @interface NotificationService ()@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; @end@implementation NotificationService // 系统接到通知后,有最多30秒在这里重写通知内容(在此方法可进行一些网络请求,如上报是否收到通知等操作) - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { NSLog(@"%s",__FUNCTION__); self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // Modify the notification content here... NSLog(@"%@",request.content); // 添加附件 //1. 下载 NSURL *url = [NSURL URLWithString:@"https://tva1.sinaimg.cn/large/008i3skNgy1gtir9lwnj0j61x40gsabl02.jpg"]; NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (!error) { //2. 保存数据 NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"download/image.jpg"]; UIImage *image = [UIImage imageWithData:data]; NSError *err = nil; [UIImageJPEGRepresentation(image, 1) writeToFile:path options:NSAtomicWrite error:&err]; //3. 添加附件 UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"remote-atta1" URL:[NSURL fileURLWithPath:path] options:nil error:&err]; if (attachment) { self.bestAttemptContent.attachments = @[attachment]; } }else{ self.bestAttemptContent.title = @"标题"; self.bestAttemptContent.subtitle = @"子标题"; self.bestAttemptContent.body = @"body"; } //4. 返回新的通知内容 self.contentHandler(self.bestAttemptContent); }]; [task resume]; } // 处理过程超时,则收到的通知直接展示出来 - (void)serviceExtensionTimeWillExpire { NSLog(@"%s",__FUNCTION__); self.contentHandler(self.bestAttemptContent); }@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进行关联
iOS|iOS 通知扩展插件
文章图片

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

自定义UI
  • 如果我们想要隐藏系统默认的内容页面,也就是下面的那部分,头是隐藏不了的;只需要在Info.plist里添加字段UNNotificationExtensionDefaultContentHidden,bool类型并设置其值为YES;
  • 可以直接修改stroryboard
    iOS|iOS 通知扩展插件
    文章图片

  • 添加Action,可以添加基本的事件
#import "NotificationViewController.h" #import #import @interface NotificationViewController () @property IBOutlet UILabel *label; @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end@implementation NotificationViewController- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"%s",__FUNCTION__); // 添加action UNNotificationAction * likeAction; //喜欢 UNNotificationAction * ingnoreAction; //取消 UNTextInputNotificationAction * inputAction; //文本输入likeAction = [UNNotificationAction actionWithIdentifier:@"action_like" title:@"点赞" options:UNNotificationActionOptionForeground]; inputAction = [UNTextInputNotificationAction actionWithIdentifier:@"action_input"title:@"评论" options:UNNotificationActionOptionForegroundtextInputButtonTitle:@"发送"textInputPlaceholder:@"说点什么"]; ingnoreAction = [UNNotificationAction actionWithIdentifier:@"action_cancel"title:@"忽略" options:UNNotificationActionOptionDestructive]; NSString *categoryWithIdentifier = @"myNotificationCategory"; // 和info.plist中配置的id一样 UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:categoryWithIdentifier actions:@[likeAction,inputAction,ingnoreAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone]; NSSet *sets = [NSSet setWithObjects:category,nil]; [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:sets]; }- (void)didReceiveNotification:(UNNotification *)notification { self.label.text = notification.request.content.body; NSLog(@"didReceiveNotification:%@",notification.request.content); for (UNNotificationAttachment * attachment in notification.request.content.attachments) { NSLog(@"url:%@",attachment.URL); // 显示图片 if([attachment.URL startAccessingSecurityScopedResource]){ NSData *data = [NSData dataWithContentsOfURL:attachment.URL]; self.imageView.image = [UIImage imageWithData:data]; [attachment.URL stopAccessingSecurityScopedResource]; }} }- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion { NSLog(@"response:%@",response); if ([response.actionIdentifier isEqualToString:@"action_like"]) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ completion(UNNotificationContentExtensionResponseOptionDismiss); }); } else if ([response.actionIdentifier isEqualToString:@"action_input"]) { UNTextInputNotificationResponse *inputAction = (UNTextInputNotificationResponse*)response; NSLog(@"输入内容:%@",inputAction.userText); // TODO: 发送评论 completion(UNNotificationContentExtensionResponseOptionDismiss); } else if ([response.actionIdentifier isEqualToString:@"action_cancel"]) { completion(UNNotificationContentExtensionResponseOptionDismiss); } else { completion(UNNotificationContentExtensionResponseOptionDismiss); } completion(UNNotificationContentExtensionResponseOptionDoNotDismiss); } @end

  • info.plist
iOS|iOS 通知扩展插件
文章图片

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

  • 参考1
  • 参考2
  • 参考3

    推荐阅读