介紹
User Notifications Framework 是蘋果在 WWDC 2016 推出的揪漩。iOS 10 中以前雜亂的和通知相關(guān)的 API 都被統(tǒng)一了鸣驱,現(xiàn)在開發(fā)者可以使用獨(dú)立的 UserNotifications.framework 來(lái)集中管理和使用 iOS 系統(tǒng)中通知的功能。在此基礎(chǔ)上术瓮,Apple 還增加了撤回單條通知康聂,更新已展示通知,中途修改通知內(nèi)容胞四,在通知中展示圖片視頻恬汁,自定義通知 UI 等一系列新功能,非常強(qiáng)大辜伟。
iOS 10 以前的推送
iOS 10 以前推送分為 Local Notifications(本地推送) 和 Remote Notifications(遠(yuǎn)程推送)氓侧。
本地推送:通過(guò) App 本地定制,加入到系統(tǒng)的 Schedule 里导狡,然后在指定的時(shí)間推送指定文字约巷。
遠(yuǎn)程推送:通過(guò)服務(wù)端向蘋果推送服務(wù)器 Apple Push Notification Service (APNs) 發(fā)送 Notification Payload,之后 APNs 再將推送下發(fā)到指定設(shè)備的 指定 App 上烘豌。
User Notifications Framework
基本配置
如果只是簡(jiǎn)單的本地推送载庭,跳過(guò) 1 、2 步驟廊佩,直接到步驟 3倍踪。
1巢价、 如果你的 App 有遠(yuǎn)端推送的話,那你需要開發(fā)者賬號(hào)的,需要新建一個(gè)對(duì)應(yīng)你 bundle 的 push 證書席怪。?具體的證書制作請(qǐng)參考這里
2、 Capabilities 中打開 Push Notifications 開關(guān)在 XCode7 中這里的開關(guān)不打開费封,推送也是可以正常使用的涡匀,但是在 XCode8 中,這里的開關(guān)必須要打開践剂,不然會(huì)報(bào)錯(cuò):
Error Domain=NSCocoaErrorDomain Code=3000 "未找到應(yīng)用程序的“aps-environment”的授權(quán)字符串" UserInfo={NSLocalizedDescription=未找到應(yīng)用程序的“aps-environment”的授權(quán)字符串}
權(quán)限申請(qǐng)
在使用 UserNotifications 框架的 API 的時(shí)候鬼譬,首先要導(dǎo)入 UserNotifications 框架:
#import <UserNotifications/UserNotifications.h>
注冊(cè)推送
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
? ? if (!error)
? ? ? ? {
? ? ? ? ? ? NSLog(@"請(qǐng)求授權(quán)成功");
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? NSLog(@"請(qǐng)求授權(quán)失敗");
? ? ? ? }
}];
Notification settings:之前注冊(cè)推送服務(wù),用戶點(diǎn)擊了同意還是不同意逊脯,以及用戶之后又做了怎樣的更改我們都無(wú)從得知优质,現(xiàn)在 apple 開放了這個(gè) API,我們可以直接獲取到用戶的設(shè)定信息了。注意 UNNotificationSettings 是只讀對(duì)象哦巩螃,不能直接修改演怎!只能通過(guò)以下方式獲取
[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];
獲取設(shè)備的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處于前臺(tái)接收通知時(shí)
// 只有app處于前臺(tái)狀態(tài)下才會(huì)調(diào)用,后臺(tái)狀態(tài)或者應(yīng)用殺死下是不會(huì)調(diào)用這個(gè)方法的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler?
// App通知的點(diǎn)擊事件
// 用戶點(diǎn)擊消息才會(huì)觸發(fā)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler?
蘋果把本地通知跟遠(yuǎn)程通知合二為一避乏。區(qū)分本地通知跟遠(yuǎn)程通知的類是UNPushNotificationTrigger.h 類中爷耀,UNPushNotificationTrigger 的類型是新增加的。
UNPushNotificationTrigger (遠(yuǎn)程通知) 遠(yuǎn)程推送的通知類型
UNTimeIntervalNotificationTrigger (本地通知) 一定時(shí)間之后拍皮,重復(fù)或者不重復(fù)推送通知歹叮。我們可以設(shè)置timeInterval(時(shí)間間隔)和repeats(是否重復(fù))。
UNCalendarNotificationTrigger(本地通知) 一定日期之后铆帽,重復(fù)或者不重復(fù)推送通知 例如盗胀,你每天8點(diǎn)推送一個(gè)通知,只要dateComponents為8锄贼,如果你想每天8點(diǎn)都推送這個(gè)通知票灰,只要repeats為YES就可以了。
UNLocationNotificationTrigger (本地通知)地理位置的一種通知宅荤,
當(dāng)用戶進(jìn)入或離開一個(gè)地理區(qū)域來(lái)通知屑迂。
內(nèi)容
以前只能展示一條文字,現(xiàn)在可以有 title 冯键、subtitle 以及 body 了惹盼。
定制方法如下:
//本地通知
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"CALENDAR";
content.subtitle = @"Lunch";
content.body = @"Today at 12:00 PM";
content.badge = @1;
//遠(yuǎn)程推送
{
"aps" : {
? ? "alert" : {?
? ? ? ? ?"title" : "CALENDAR",?
? ? ? ? ?"subtitle" : "Lunch", ? ? ? ??
? ? ? ? ?"body" : "Today at 12:00 PM"
? ? ? ? ? ? ? ? },
? ? "badge" : 1
? ? ? ? },
}
Triggers
UNTimeIntervalNotificationTrigger 定時(shí)推送
UNCalendarNotificationTrigger 定期推送
UNLocationNotificationTrigger 定點(diǎn)推送
//60 秒后提醒
//timeInterval:?jiǎn)挝粸槊耄╯) ?repeats:是否循環(huán)提醒
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];
//首先得導(dǎo)入#import <CoreLocation/CoreLocation.h>,不然會(huì)regin創(chuàng)建有問(wèn)題惫确。
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) {
}];
推送小結(jié)
整個(gè)推送的過(guò)程如下
Local Notifications 通過(guò)定義 Content 和 Trigger 向 UNUserNotificationCenter 進(jìn)行 request 這三部曲來(lái)實(shí)現(xiàn)手报。
Remote Notifications 則向 APNs 發(fā)送 Notification Payload 。
Notification Handling
設(shè)定了推送改化,然后就結(jié)束了掩蛤?iOS 10 并沒(méi)有這么簡(jiǎn)單!
通過(guò)實(shí)現(xiàn)協(xié)議陈肛,使 App 處于前臺(tái)時(shí)捕捉并處理即將觸發(fā)的推送:
@interface AppDelegate () <UNUserNotificationCenterDelegate>
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
? ? completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}
讓它只顯示 alert 和 sound ,而忽略 badge 揍鸟。
Notification Management
徹底掌控整個(gè)推送周期:
Local Notification 通過(guò)更新 request
Remote Notification 通過(guò)新的字段 apns-collapse-id
通過(guò)之前的 addNotificationRequest: 方法,在 id 不變的情況下重新添加句旱,就可以刷新原有的推送阳藻。
NSString *requestIdentifier = @"sampleRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? content:newContent
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? trigger:newTrigger1];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
刪除計(jì)劃的推送:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
此外 UNUserNotificationCenter.h 中還有諸如刪除所有推送、查看已經(jīng)發(fā)出的推送谈撒、刪除已經(jīng)發(fā)出的推送等等強(qiáng)大的接口腥泥。
刷新原有的推送后,在通知中心的顯示里啃匿,也會(huì)有相應(yīng)的變化蛔外,這里注意第 2 條信息,現(xiàn)在比分是 1:0
比分刷新后為 1:1,在不產(chǎn)生新的推送條目的情況下位置被前置了冒萄!
上面簡(jiǎn)單介紹了 iOS 10 的新框架 User Notifications Framework,了解完 iOS 10 的框架之后橙数,還要適配iOS 8 9 系統(tǒng)尊流,是不是覺(jué)得很麻煩,筆者最近發(fā)現(xiàn)了一款 SDK ----?MobPush灯帮,兼容 iOS 8-12 系統(tǒng)崖技,接入非常簡(jiǎn)單,3行代碼就可以搞定推送钟哥。
MPushNotificationConfiguration *configuration = [[MPushNotificationConfiguration alloc] init];
configuration.types = MPushAuthorizationOptionsBadge | MPushAuthorizationOptionsSound | MPushAuthorizationOptionsAlert;
[MobPush setupNotification:configuration];
同時(shí)迎献,MobPush?支持多樣化推送場(chǎng)景、用戶分群腻贰、AB 測(cè)試吁恍、智能推送等等功能,還有完善的數(shù)據(jù)統(tǒng)計(jì)后臺(tái)可以從多個(gè)維度實(shí)時(shí)了解 APP 和用戶的使用情況播演,了解更多冀瓦。