User Notifications Framework 是蘋果在 WWDC 2016 推出的。iOS 10 中之前雜亂的和通知相關的 API 都被統一了,如今開發者可使用獨立的 UserNotifications.framework 來集中管理和使用 iOS 系統中通知的功能。在此基礎上,Apple 還增長了撤回單條通知,更新已展現通知,中途修改通知內容,在通知中展現圖片視頻,自定義通知 UI 等一系列新功能,很是強大。服務器
iOS 10 之前推送分爲 Local Notifications(本地推送) 和 Remote Notifications(遠程推送)。app
本地推送:經過 App 本地定製,加入到系統的 Schedule 裏,而後在指定的時間推送指定文字。框架
遠程推送:經過服務端向蘋果推送服務器 Apple Push Notification Service (APNs) 發送 Notification Payload,以後 APNs 再將推送下發到指定設備的 指定 App 上。ide
若是隻是簡單的本地推送,跳過 1 、2 步驟,直接到步驟 3。測試
一、 若是你的 App 有遠端推送的話,那你須要開發者帳號的,須要新建一個對應你 bundle 的 push 證書。 具體的證書製做請參考這裏
二、 Capabilities 中打開 Push Notifications 開關在 XCode7 中這裏的開關不打開,推送也是能夠正常使用的,可是在 XCode8 中,這裏的開關必需要打開,否則會報錯:spa
Error Domain=NSCocoaErrorDomain Code=3000 "未找到應用程序的「aps-environment」的受權字符串" UserInfo={NSLocalizedDescription=未找到應用程序的「aps-environment」的受權字符串}
在使用 UserNotifications 框架的 API 的時候,首先要導入 UserNotifications 框架:代理
#import <UserNotifications/UserNotifications.h>
註冊推送code
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error) { NSLog(@"請求受權成功"); } else { NSLog(@"請求受權失敗"); } }];
Notification settings:以前註冊推送服務,用戶點擊了贊成仍是不一樣意,以及用戶以後又作了怎樣的更改咱們都無從得知,如今 apple 開放了這個 API,咱們能夠直接獲取到用戶的設定信息了。注意 UNNotificationSettings 是隻讀對象哦,不能直接修改!只能經過如下方式獲取component
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { NSLog(@"%@", settings); }];
打印視頻
<UNNotificationSettings: 0x6000022f9dc0; authorizationStatus: NotDetermined, notificationCenterSetting: NotSupported, soundSetting: NotSupported, badgeSetting: NotSupported, lockScreenSetting: NotSupported, carPlaySetting: NotSupported, criticalAlertSetting: NotSupported, alertSetting: NotSupported, alertStyle: None, providesAppNotificationSettings: No>
Token Registration
[[UIApplication sharedApplication] registerForRemoteNotifications];
獲取設備的Device Token
//獲取DeviceToken成功 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"deviceToken:%@",deviceString); } //獲取DeviceToken失敗 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"[DeviceToken Error]:%@\n",error.description); }
接收推送的代理方法
// App處於前臺接收通知時 // 只有app處於前臺狀態下才會調用,後臺狀態或者應用殺死下是不會調用這個方法的 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler // App通知的點擊事件 // 用戶點擊消息纔會觸發 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler
蘋果把本地通知跟遠程通知合二爲一。區分本地通知跟遠程通知的類是UNPushNotificationTrigger.h 類中,UNPushNotificationTrigger 的類型是新增長的。
UNPushNotificationTrigger (遠程通知) 遠程推送的通知類型
UNTimeIntervalNotificationTrigger (本地通知) 必定時間以後,重複或者不重複推送通知。咱們能夠設置timeInterval(時間間隔)和repeats(是否重複)。
UNCalendarNotificationTrigger(本地通知) 必定日期以後,重複或者不重複推送通知 例如,你天天8點推送一個通知,只要dateComponents爲8,若是你想天天8點都推送這個通知,只要repeats爲YES就能夠了。
UNLocationNotificationTrigger (本地通知)地理位置的一種通知,
當用戶進入或離開一個地理區域來通知。
內容
之前只能展現一條文字,如今能夠有 title 、subtitle 以及 body 了。
定製方法以下:
//本地通知 UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; content.title = @"CALENDAR"; content.subtitle = @"Lunch"; content.body = @"Today at 12:00 PM"; content.badge = @1; //遠程推送 { "aps" : { "alert" : { "title" : "CALENDAR", "subtitle" : "Lunch", "body" : "Today at 12:00 PM" }, "badge" : 1 }, }
Triggers
UNTimeIntervalNotificationTrigger 定時推送
UNCalendarNotificationTrigger 按期推送
UNLocationNotificationTrigger 定點推送
//60 秒後提醒 //timeInterval:單位爲秒(s) repeats:是否循環提醒 UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:60 repeats:NO]; // 在每週一早上 8:00 提醒 NSDateComponents *components = [[NSDateComponents alloc] init]; components.weekday = 2; components.hour = 8; UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES]; //首先得導入#import <CoreLocation/CoreLocation.h>,否則會regin建立有問題。 CLLocationCoordinate2D center1 = CLLocationCoordinate2DMake(31.234567, 117.4567890); CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center1 radius:500 identifier:@"桂林路"]; UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
Add Request
NSString *requestIdentifier = @"sampleRequest"; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:trigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
推送小結
整個推送的過程以下
Local Notifications 經過定義 Content 和 Trigger 向 UNUserNotificationCenter 進行 request 這三部曲來實現。
Remote Notifications 則向 APNs 發送 Notification Payload 。
Notification Handling
設定了推送,而後就結束了?iOS 10 並無這麼簡單!
經過實現協議,使 App 處於前臺時捕捉並處理即將觸發的推送:
@interface AppDelegate () <UNUserNotificationCenterDelegate> - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound); }
讓它只顯示 alert 和 sound ,而忽略 badge 。
Notification Management
完全掌控整個推送週期:
Local Notification 經過更新 request
Remote Notification 經過新的字段 apns-collapse-id
經過以前的 addNotificationRequest: 方法,在 id 不變的狀況下從新添加,就能夠刷新原有的推送。
NSString *requestIdentifier = @"sampleRequest"; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:newContent trigger:newTrigger1]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
刪除計劃的推送:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
此外 UNUserNotificationCenter.h 中還有諸如刪除全部推送、查看已經發出的推送、刪除已經發出的推送等等強大的接口。
刷新原有的推送後,在通知中心的顯示裏,也會有相應的變化,這裏注意第 2 條信息,如今比分是 1:0
比分刷新後爲 1:1,在不產生新的推送條目的狀況下位置被前置了!
上面簡單介紹了 iOS 10 的新框架 User Notifications Framework,瞭解完 iOS 10 的框架以後,還要適配iOS 8 9 系統,是否是以爲很麻煩,筆者最近發現了一款 SDK ---- MobPush,兼容 iOS 8-12 系統,接入很是簡單,3行代碼就能夠搞定推送。
MPushNotificationConfiguration *configuration = [[MPushNotificationConfiguration alloc] init]; configuration.types = MPushAuthorizationOptionsBadge | MPushAuthorizationOptionsSound | MPushAuthorizationOptionsAlert; [MobPush setupNotification:configuration];
同時,MobPush 支持多樣化推送場景、用戶分羣、AB 測試、智能推送等等功能,還有完善的數據統計後臺能夠從多個維度實時瞭解 APP 和用戶的使用狀況