iOS 10
以前的通知比較雜亂,把本地通知和遠程通知分開了,誕生了許多功能類似的API,很容易讓初學者犯迷糊。而iOS 10
的通知把API
做了統一,利用獨立的UserNotifications.framework
框架來管理通知;並且,還增加了撤銷單條通知、更新已展示通知、中途修改通知內容等等,以及在通知中展示圖片視頻,自定義通知UI
等一系列新功能;總之,iOS 10
的通知功能十分強大。
瞭解通知之前,有必要了解一下通知的歷史和現狀。由於通知可以方便的提示用戶應用的狀態、傳遞重要的信息,所以自從iOS 3
引入通知以來,幾乎每個新的版本,Apple
都會增強通知的功能。
一、發展歷程:
iOS 3 - 引入推送通知
UIApplication 的 registerForRemoteNotificationTypes
與 UIApplicationDelegate
的 application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
,application(_:didReceiveRemoteNotification:)
iOS 4 - 引入本地通知
scheduleLocalNotification
,presentLocalNotificationNow:
, application(_:didReceive:)
iOS 5 - 加入通知中心頁面
iOS 6 - 通知中心頁面與 iCloud 同步
iOS 7 - 後臺靜默推送
application(_:didReceiveRemoteNotification:fetchCompletionHandle:)
iOS 8 - 重新設計notification權限請求,加入交互式通知
Actionable 通知 registerUserNotificationSettings(_:),UIUserNotificationAction
與 UIUserNotificationCategory
,application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)
iOS 9 - Text Input action
基於 HTTP/2 的推送請求 UIUserNotificationActionBehavior
,全新的 Provider API 等
二、通知應用
申請權限
// 獲取通知中心對象
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
// 申請通知權限
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"通知開啓");
} else {
NSLog(@"關閉通知");
}
}];
// 獲取授權的通知權限
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@", settings);
}];
requestAuthorizationWithOptions:
申請通知的權限,iOS 10
不再區分遠程通知和本地通知的權限申請,統一用該方法做權限申請
添加通知
// 創建通知對象
UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init]];
// 設置通知標題
noticeContent.title = @"iOS10通知";
// 設置通知子標題
noticeContent.subtitle = @"新通知學習筆記";
// 設置通知內容
noticeContent.body = @"新通知變化很大,之前本地通知和遠程推送是兩個類,現在合成一個了。";
// 添加通知的聲音
UNNotificationSound *sound = [UNNotificationSound soundNamed:@"caodi.m4a"];
noticeContent.sound = sound;
UNMutableNotificationContent
通知的內容,可以設置通知的標題、副標題、具體內容,以及通知的圖片、視頻、聲音和交互信息等等
UNNotificationSound
應用在後臺時收到通知時的提示音
觸發機制
// 如果repeats爲YES,那麼triggerWithTimeInterval的值要大於60s
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3 repeats:NO];
NSString *requestIdentifier = @"requestIdentifier";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:trigger1];
UNTimeIntervalNotificationTrigger
設置通知觸發的條件,分爲以下幾類:
- 1.
UNPushNotificaitonTrigger
推送服務的Trigger,由系統創建
- 2.
UNTimeIntervalNotificaitonTrigger
時間觸發器,可以設置多長時間後觸發通知,repeats
參數爲是否重複觸發,如果設置YES
,那麼triggerWithTimeInterval
的時間必須大於60s
- 3.
UNCalendarNotificaitonTrigger
日期觸發器,可以設置特定日期觸發
- 4.
UNLocationNotificaitonTrigger
位置觸發器,用於到達特定位置後才觸發通知,需要設置CLRegion
的具體區域
發送通知
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
NSLog(@"發送通知出錯: %@", error);
}];
addNotificationRequest:withCompletionHandler:
把通知添加到通知中心,就可以發送通知了
擴展通知
我們可以在通知中添加聲音、圖片和視頻,來豐富通知的內容,在支持3D-touch
的手機上,重壓之後會全面顯示;另外,我們也可以添加交互式通知,進一步提高用戶體驗
UNNotificationationAttachment
通知的附近,我們可以在附近中添加圖片、音頻或視頻。
添加圖片
UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
NSString *imageFile = [[NSBundle mainBundle] pathForResource:@"sport" ofType:@"png"];
UNNotificationAttachment *imageAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"imageAttachment" URL:[NSURL fileURLWithPath:imageFile] options:nil error:nil];
NSAssert(imageAttachment != nil, @"imageAttach 不能爲空");
noticeContent.attachments = @[imageAttachment];
添加視頻
UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
NSString *movieFile = [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"mp4"];
UNNotificationAttachment *movieAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"movieAttachment" URL:[NSURL fileURLWithPath:movieFile] options:nil error:nil];
NSAssert(movieAttachment != nil, @"movieAttach 不能爲空");
noticeContent.attachments = @[movieAttachment];
添加交互式通知
添加交互式通知
UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
// 文字action
UNTextInputNotificationAction *action1 = [UNTextInputNotificationAction actionWithIdentifier:@"replyAction" title:@"文字回覆" options:UNNotificationActionOptionNone];
// 進入應用action
UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"enterAction" title:@"進入應用" options:UNNotificationActionOptionForeground];
// 取消action
UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"cancelAction" title:@"取消" options:UNNotificationActionOptionDestructive];
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"Categroy" actions:@[action1, action2, action3] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:category]];
noticeContent.categoryIdentifier = @"Categroy";
獲取交互動作
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;
if ([categoryIdentifier isEqualToString:@"Categroy"]) {
if ([response.actionIdentifier isEqualToString:@"replyAction"]) {
UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse*)response;
NSString *userText = textResponse.userText;
NSLog(@"您輸入的內容:%@", userText);
} else if ([response.actionIdentifier isEqualToString:@"enterAction"]) {
NSLog(@"點擊進入了應用");
} else {
NSLog(@"點擊了取消");
}
}
completionHandler();
}
iOS 10
把接收通知的方法做了統一,不再區分接收本地和遠程的通知,只分前臺和後臺時受到的通知。
接收通知的步驟:
1.設置通知的代理,一般設置在AppDelegate
裏
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
2.實現代理方法
// 應用在前臺收到通知的處理方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
// 應用在後臺收到通知的處理方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
自定義通知樣式
iOS 10
可以設置通知的UI
樣式,更加方便給用戶定製化。必須用iPhone7或iPhone7 Plus,iPhone6s及以下硬件,即使升級到iOS 10
也無法顯示自定義通知的樣式
1.創建自定義通知UI
文件,在Xcode
中File
->New
->Targe
會出現下面的視圖
其中,與通知相關的擴展有兩個:Notification Content
和 Notification Service Extension
,前者是自定義通知的類型,後者是我們收到遠程通知後,在展示之前對通知的修改。所以,我們採用前者
2.修改通知視圖的控制器,自定義通知樣式
NotificationViewController
文件:
- (void)didReceiveNotification:(UNNotification *)notification
可以設置UI顯示的數據
MainInterface.storyboard
文件
我們可以通過這個storyboard
來具體定製通知的樣式
3.應用自定義通知樣式
修改NotificationViewController
的info.plist
文件
UNNotificationExtensionCategory
UNNotificationCategory
的標識,需要設置爲我們的通知的標識
UNNotificationExtensionInitialContentSizeRatio
通知內容顯示的比例大小,默認爲1
UNNotificationExtensionDefaultContentHidden
是否隱藏默認通知,設置爲YES
後,默認通知會隱藏
移除通知
[[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[@"requestIdentifier"]];
至此,iOS 10
本地通知已經解析完畢,下一篇是遠程通知,……
實例項目
https://github.com/BirdandLion/UNNotificationDemo.git
參考資料
https://developer.apple.com/reference/usernotifications