iOS 10 的推送 User Notifications Framework

介紹

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 和用戶的使用情況播演,了解更多冀瓦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市写烤,隨后出現(xiàn)的幾起案子翼闽,更是在濱河造成了極大的恐慌,老刑警劉巖洲炊,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件感局,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡暂衡,警方通過(guò)查閱死者的電腦和手機(jī)询微,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狂巢,“玉大人拓提,你說(shuō)我怎么就攤上這事∷肀欤” “怎么了代态?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)疹吃。 經(jīng)常有香客問(wèn)我蹦疑,道長(zhǎng),這世上最難降的妖魔是什么萨驶? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任歉摧,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘叁温。我一直安慰自己再悼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布膝但。 她就那樣靜靜地躺著冲九,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跟束。 梳的紋絲不亂的頭發(fā)上莺奸,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音冀宴,去河邊找鬼灭贷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛略贮,可吹牛的內(nèi)容都是我干的甚疟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼逃延,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼古拴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起真友,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤黄痪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后盔然,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桅打,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年愈案,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挺尾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡站绪,死狀恐怖遭铺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恢准,我是刑警寧澤魂挂,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站馁筐,受9級(jí)特大地震影響涂召,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜敏沉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一果正、第九天 我趴在偏房一處隱蔽的房頂上張望炎码。 院中可真熱鬧,春花似錦秋泳、人聲如沸潦闲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)歉闰。三九已至,卻和暖如春舍杜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赵辕。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工既绩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人还惠。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓饲握,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚕键。 傳聞我的和親對(duì)象是個(gè)殘疾皇子救欧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容