iOS 通知擴充套件外掛
目錄
-
Notification Content Extension
- 通知內容擴充套件,是在展示通知時展示一個自定義的使用者介面。
-
Notification Service Extension
- 通知服務擴充套件,是在收到通知後,展示通知前,做一些事情的。比如,增加附件,網路請求等。
Notification Service Extension
- 目前只找到aps推送支援
- 主要是處理一下附件相關的下載
新建一個target
程式碼實現
@interface NotificationService : UNNotificationServiceExtension
@end
#import "NotificationService.h"
#import <UIKit/UIKit.h>
@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進行關聯
- 找到這個 UNNotificationExtensionCategory,寫到Notification Service Extension中,可以配置多個,對應多個介面
self.bestAttemptContent.categoryIdentifier = @"myNotificationCategory";// 和NotificationConentExtension關聯
self.contentHandler(self.bestAttemptContent);
自定義UI
-
如果我們想要隱藏系統預設的內容頁面,也就是下面的那部分,頭是隱藏不了的;只需要在Info.plist裡新增欄位UNNotificationExtensionDefaultContentHidden,bool型別並設定其值為YES;
-
可以直接修改stroryboard
-
新增Action,可以新增基本的事件
#import "NotificationViewController.h"
#import <UserNotifications/UserNotifications.h>
#import <UserNotificationsUI/UserNotificationsUI.h>
@interface NotificationViewController () <UNNotificationContentExtension,UIActionSheetDelegate>
@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:UNNotificationActionOptionForeground textInputButtonTitle:@"傳送"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
- 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"
}
}