本文作者:陳裕發(fā), 騰訊系統(tǒng)測(cè)試工程師痘系,由騰訊WeTest整理發(fā)表菲嘴。
1、引言
開(kāi)發(fā)iOS系統(tǒng)中的Push推送汰翠,通常有以下3種情況:
1)在線Push:比如QQ龄坪、微信等IM界面處于前臺(tái)時(shí),聊天消息和指令都會(huì)通過(guò)IM自建的網(wǎng)絡(luò)長(zhǎng)連接通道推送過(guò)來(lái)复唤,這種Push在本文中暫且稱為“在線Push”健田;
2)本地Push:這種就是最常見(jiàn)的iOS系統(tǒng)通知(作用相當(dāng)于傳統(tǒng)PC端的提示窗口,在iOS10以后全部整合到UserNotifications.framework框架了)佛纫,不涉及任何網(wǎng)絡(luò)數(shù)據(jù)妓局,僅僅是讓APP擁有一個(gè)統(tǒng)一系統(tǒng)通知方式而已总放,比如:鬧鐘的定時(shí)提醒等;
3)離線/遠(yuǎn)程Push:這就是iOS程序員最熟悉的APNs這一套東西了好爬,它使得APP處于后臺(tái)或者被kill的情況下仍能收到網(wǎng)絡(luò)通知局雄,最常見(jiàn)的應(yīng)場(chǎng)景就是IM聊天工具了。
? ?? ???本文將對(duì)iOS Push的在線push存炮、本地push及離線(遠(yuǎn)程)push進(jìn)行了詳細(xì)梳理炬搭,介紹相關(guān)邏輯、測(cè)試時(shí)要注意的要點(diǎn)以及相關(guān)工具的使用穆桂。小小的Push背后蘊(yùn)藏著大大的邏輯尚蝌,我們一起來(lái)學(xué)習(xí)吧!
2充尉、相關(guān)文章
? ?? ???《移動(dòng)端實(shí)時(shí)消息推送技術(shù)淺析》
? ?? ???《iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路飘言、技術(shù)原理及缺陷等》
? ?? ???《信鴿團(tuán)隊(duì)原創(chuàng):一起走過(guò) iOS10 上消息推送(APNS)的坑》
? ?? ???《掃盲貼:淺談iOS和Android后臺(tái)實(shí)時(shí)消息推送的原理和區(qū)別》
3、iOS的Push種類
? ?? ???3.1 在線push
在線push:當(dāng)用戶在線(APP在前臺(tái))時(shí)驼侠,收到的狀態(tài)欄的消息提醒姿鸿,稱為在線push。這個(gè)功能與蘋果系統(tǒng)無(wú)關(guān)倒源,是我們自己的APP開(kāi)發(fā)的一種功能苛预,該push與設(shè)置中是否打開(kāi)“通知”無(wú)關(guān)。
這里以iOS Qzone為例笋熬,當(dāng)APP在前臺(tái)時(shí)热某,自己發(fā)的說(shuō)說(shuō)被點(diǎn)贊了,收到的在線push如下:
? ?? ???3.2 離線/遠(yuǎn)程push
離線push:當(dāng)APP在離線(kill掉進(jìn)程胳螟、切到后臺(tái)昔馋、鎖屏)時(shí),收到的消息提醒糖耸,稱為離線push秘遏。離線push是需要經(jīng)過(guò)蘋果的APNs服務(wù)器才可以推送到某臺(tái)設(shè)備的某個(gè)APP上的,這是和本地push的本質(zhì)區(qū)別嘉竟。push與設(shè)置中是否打開(kāi)“通知”有關(guān)邦危。
這里最簡(jiǎn)單的以大家常用的手機(jī)QQ為例,當(dāng)APP在后臺(tái)舍扰、鎖屏或者被kiil了進(jìn)程時(shí)倦蚪,收到了消息:
一種特殊的遠(yuǎn)程push:靜默push
? ?? ???嚴(yán)格來(lái)說(shuō),靜默push屬于遠(yuǎn)程push的一種特殊情況边苹,靜默push用的場(chǎng)景不較少陵且,這里只做簡(jiǎn)要介紹。
? ?? ???首先我們看看離線(遠(yuǎn)程)push與靜默push的區(qū)別:
? ?? ???【普通離線(遠(yuǎn)程)push】:收到推送后(有文字有聲音)勾给,點(diǎn)開(kāi)通知滩报,進(jìn)入APP后,才執(zhí)行-- (void)application:(UIApplication didReceiveRemoteNotification:(NSDictionary fetchCompletionHandler:(void result))handler *)application *)userInfo (^)(UIBackgroundFetchResult
? ?? ???【靜默push】:收到推送(沒(méi)有文字沒(méi)有聲音)播急,不用點(diǎn)開(kāi)通知脓钾,不用打開(kāi)APP,就能執(zhí)行(void)application:(UIApplication )application)userInfo didReceiveRemoteNotification:(NSDictionary fetchCompletionHandler:(void (^)(UIBackgroundFetchResultresult))handler桩警,用戶完全感覺(jué)不到可训。
? ?? ???所以靜默push又被我們稱做 Background Remote Notification(后臺(tái)遠(yuǎn)程推送)。靜默推送是在iOS7之后推出的一種推送方式捶枢。它與其他推送的區(qū)別在于允許應(yīng)用收到通知后在后臺(tái)(background)狀態(tài)下運(yùn)行一段代碼握截,可用于從服務(wù)器獲取內(nèi)容更新。
? ?? ???3.3 本地push
本地push:本地推送和遠(yuǎn)程推送的功能是一樣的烂叔,都是要提醒用戶去做某些事情谨胞。但是和遠(yuǎn)程推送不同的就是本地推送是不需要設(shè)備聯(lián)網(wǎng)的,而遠(yuǎn)程推送是必需要設(shè)備聯(lián)網(wǎng)的蒜鸡,因?yàn)橹挥新?lián)網(wǎng)狀態(tài)下胯努,才能和蘋果的APNs服務(wù)器建立長(zhǎng)連接,從而推送消息逢防。本地推送是由App自己設(shè)定的叶沛,并且發(fā)送給安裝此App的這臺(tái)設(shè)備,屬于一對(duì)一的對(duì)應(yīng)關(guān)系忘朝。比較典型的應(yīng)用是鬧鐘類似的場(chǎng)景局嘁。該push與設(shè)置中是否打開(kāi)“通知”有關(guān)。
最容易看到本地push的場(chǎng)景悦昵,可以直接在手機(jī)設(shè)置一個(gè)計(jì)時(shí)器约巷,計(jì)時(shí)器時(shí)間到了就會(huì)彈出本地push:
? ?? ???由于本地push原理和作用相對(duì)于在線push和離線push都更為簡(jiǎn)單明了,下文主要介紹在線push和離線push
4旱捧、本地push實(shí)現(xiàn)
? ?? ???4.1 iOS10以前本地push彈出方式
? ?? ???試驗(yàn)過(guò)iOS10以前的本地push方法在iOS10+的系統(tǒng)也能使用独郎,不過(guò)可能有些參數(shù)不生效枚赡。
1)立即展示( iOS10以前)
? ?? ???本地push稍微簡(jiǎn)單贫橙,有兩種方式可以調(diào)用,一種是presentLocalNotificationNow方法卢肃,立即展示本地push:
2)延遲展示( iOS10以前)
? ?? ???另一種是用scheduleLocalNotification方法按計(jì)劃來(lái)彈本地推送:
? ?? ???如果使用這種方法疲迂,需要對(duì)推送的時(shí)間進(jìn)行設(shè)置郑气,舉個(gè)例子奏属,設(shè)為5秒后:
? ?? ???4.2 設(shè)置本地push內(nèi)容( iOS10以前)
? ?? ???其中alertBody是消息內(nèi)容鎖屏與不鎖屏?xí)r效果如下:
? ?? ???applicationIconBadgeNumber是消息數(shù)量愧驱,我們可以看到這里設(shè)置為66:
? ?? ???4.3 處理本地push ( iOS10以前)
1)App沒(méi)有啟動(dòng)情況下處理本地push
? ?? ???這種情況下吻商,當(dāng)點(diǎn)擊通知時(shí),會(huì)啟動(dòng)App糟红,而在App中艾帐,開(kāi)發(fā)人員可以通過(guò)實(shí)現(xiàn)AppDelegate中的方法:- (BOOL)application:UIApplication)application didFinishLaunchingWithOptions:NSDictionary *)launchOptions,然后從lauchOptions中獲取App啟動(dòng)的原因盆偿,若是因?yàn)楸镜赝ㄖ獍郑瑒t可以App啟動(dòng)時(shí)對(duì)App做對(duì)應(yīng)的操作,比方說(shuō)跳轉(zhuǎn)到某個(gè)畫(huà)面等等事扭。
2)App運(yùn)行在后臺(tái)及前臺(tái)
? ?? ???上面的2種情況的處理基本一致捎稚, 不同點(diǎn)只有當(dāng)運(yùn)行再后臺(tái)的時(shí)候,會(huì)有彈窗提示用戶另外一個(gè)App有通知,對(duì)于本地通知單的處理都是通過(guò)AppDelegate的方法:- (void)application
? ?? ???UIApplication )application didReceiveLocalNotification:UILocalNotification *)notification來(lái)處理的今野。
? ?? ???4.4 iOS10以后本地push彈出方式
? ?? ???iOS10以后葡公,本地通知可以由使用 UNUserNotificationCenter來(lái)管理。
? ?? ???創(chuàng)建方法:
? ?? ???接下來(lái)需要需創(chuàng)建一個(gè)包含待通知內(nèi)容的 UNMutableNotificationContent 對(duì)象:
? ?? ???在iOS上可以通過(guò)以下幾種觸發(fā)器來(lái)觸發(fā)本地push:
? ?? ???UNCalendarNotificationTrigger 傳送本地通知的日期和時(shí)間条霜;
? ?? ???UNTimeIntervalNotificationTrigger 傳遞本地通知之前必須過(guò)期的時(shí)間催什;
? ?? ???UNLocationNotificationTrigger 用戶必須達(dá)到的地理位置才能提供本地通知;
? ?? ???UNPushNotificationTrigger 表示通知是從Apple推送通知服務(wù)發(fā)送的對(duì)象蛔外。
? ?? ???假如以時(shí)間間隔(TimeInterval)來(lái)觸發(fā),則設(shè)置觸發(fā)器代碼為:
? ?? ???推送本地push的代碼為:
5溯乒、在線夹厌、離線(遠(yuǎn)程)push流程
? ?? ???5.1 在線push流程
? ?? ???在線push相對(duì)簡(jiǎn)單,因?yàn)槭莾?nèi)部實(shí)現(xiàn)裆悄,具體流程如上面所示矛纹。
1)判斷app是否在線:
? ?? ???此處可以根據(jù)APP自身的后臺(tái)策略如上一次與后臺(tái)交互的時(shí)間等方法來(lái)判斷APP是否在線或者離線。認(rèn)為在線光稼,會(huì)發(fā)送在線push或南,否則,發(fā)送離線push艾君。
2)在線push有以下幾個(gè)特點(diǎn):
? ?? ???不需要經(jīng)過(guò)蘋果APNs采够;
? ?? ???需要自己實(shí)現(xiàn)長(zhǎng)鏈接;
? ?? ???代碼在app內(nèi)部實(shí)現(xiàn)冰垄。
? ?? ???5.2 離線(遠(yuǎn)程)push流程
? ?? ???主要流程為:
? ?? ???1)服務(wù)器端將消息先發(fā)送到蘋果的APNs蹬癌;
? ?? ???2)由蘋果的APNs將消息推送到客戶的設(shè)備端;
? ?? ???3)由iOS系統(tǒng)將接收到的消息傳遞給相應(yīng)的App虹茶。
? ?? ???簡(jiǎn)而言之離線push是蘋果系統(tǒng)的行為逝薪,與app狀態(tài)無(wú)關(guān),能夠直接推送到指定手機(jī)的指定app蝴罪。
? ?? ???在進(jìn)一步了解離線push前董济,我們有必要先了解幾個(gè)名詞。
? ?? ???【離線push名詞解釋】:
(1)名詞解釋之APNs
? ?? ???APNs:Apple Push Notification service(蘋果推送通知服務(wù))要门。
? ?? ???APNs主要用于以下場(chǎng)景:當(dāng)用戶主動(dòng)殺掉 APP虏肾,或者 APP 進(jìn)入后臺(tái)超過(guò)約定時(shí)長(zhǎng)時(shí),APP會(huì)被kill欢搜,這樣保障了前臺(tái) APP 的流暢性询微,也延長(zhǎng)了手機(jī)的使用時(shí)長(zhǎng),獲得了較好的用戶體驗(yàn)狂巢,但是這也意味著撑毛,服務(wù)器無(wú)法主動(dòng)和用戶交互(如推送實(shí)時(shí)消息等),所以蘋果推出了 APNs,允許設(shè)備和服務(wù)器分別與蘋果的推送通知服務(wù)器保持長(zhǎng)連接狀態(tài)藻雌。
? ?? ???關(guān)于APNs的更新有以下幾點(diǎn):
? ?? ???iOS 8以后雌续,APNs推送的字節(jié)是2k,iOS8以前是256字節(jié)胯杭;
? ?? ???iOS 9以后APNs支持HTTP/2協(xié)議棧驯杜,優(yōu)化長(zhǎng)連接,具有標(biāo)準(zhǔn)的HTTP返回和管道復(fù)用技術(shù)做个;
? ?? ???iOS 10以后鸽心,推送的字節(jié)是4k,APNs可根據(jù)推送消息的唯一標(biāo)示符查詢某條消息是否被用戶閱讀居暖,可更新某一推送消息顽频,而不用發(fā)重讀的多條消息。
? ?? ???關(guān)于APNs更全面的介紹可以看官方文檔:點(diǎn)此進(jìn)入太闺。
(2)名詞解釋之payload
? ?? ???什么是payload糯景?對(duì)于每一條發(fā)送給APNs的推送消息,都包含一個(gè)payload省骂,通常是組成了一個(gè)JSON的Dictionary蟀淮,這其中必不可少的是aps屬性,它對(duì)應(yīng)的value也是一個(gè)Dictionary钞澳,包含一些但不限于以下內(nèi)容:標(biāo)題怠惶、副標(biāo)題、內(nèi)容轧粟、附件甚疟、category等,如
(3)名詞解釋之device token
? ?? ???什么是device token逃延?我們看一下官方的簡(jiǎn)介:
? ?? ???device token: APNs uses device tokens to identify each unique app and device combination. It also uses them to authenticate the routing of remote notifications sent to a device.(device token是APNs用于區(qū)分識(shí)別每個(gè)iOS設(shè)備和設(shè)備上不同app的一個(gè)標(biāo)識(shí)符览妖,還可以用于APNs通過(guò)它將推送消息路由到指定設(shè)備上)
即:device token里包含了device id和bundle id的信息,但是device id和bundle id不會(huì)確定唯一的device token揽祥。
? ?? ???但是讽膏,這里有個(gè)坑拄丰,查資料得知,iOS8及之前的iOS系統(tǒng)奄侠,對(duì)于同一部手機(jī)载矿,如果卸載后重裝APP的話,device token是不會(huì)變的弯洗,在token變了以后,老的token藐吮,就被認(rèn)為是無(wú)效了,蘋果不會(huì)對(duì)這部分無(wú)效的token推送逃贝。但是谣辞,對(duì)iOS9及以后的iOS系統(tǒng),對(duì)于同一部手機(jī)沐扳,卸載后重裝APP的device token是會(huì)發(fā)生變化的泥从,而且老的token不會(huì)無(wú)效,還可以正常推送迫皱,這應(yīng)該是蘋果的一個(gè)bug歉闰,但是蘋果也沒(méi)有修復(fù)這個(gè)問(wèn)題辖众,所以這個(gè)需要開(kāi)發(fā)者自己來(lái)解決卓起,否則容易出現(xiàn)一個(gè)app收到多個(gè)push的問(wèn)題。
? ?? ???官方的說(shuō)法是:
? ?? ???To protect user privacy, do not use device tokens to identify user devices. Device tokens change when the user updates the operating system and when a device’s data and settings are erased. As a result, apps should always request the current device token at launch time.(即此舉為了保護(hù)用戶隱私凹炸,device token會(huì)在更新系統(tǒng)戏阅、擦除設(shè)置重置后變化,在一定時(shí)間后會(huì)過(guò)期)
【離線push詳細(xì)流程】
? ?? ???知道了以上概念后我們重新來(lái)看一下離線(遠(yuǎn)程)push的詳細(xì)流程:
? ?? ???1) 首先是應(yīng)用程序注冊(cè)消息推送啤它;
? ?? ???2) iOS跟APNS Server要deviceToken奕筐。應(yīng)用程序接受deviceToken;
? ?? ???3) 應(yīng)用程序?qū)eviceToken發(fā)送給PUSH服務(wù)端程序变骡;
? ?? ???4) 服務(wù)端程序向APNS服務(wù)發(fā)送消息离赫;
? ?? ???5) APNS服務(wù)將消息發(fā)送給iPhone應(yīng)用程序。
? ?? ???值得注意的是塌碌,當(dāng)由于用戶反復(fù)卸載重裝程序(雖然概率很性ㄐ亍)等原因?qū)е露鄠€(gè)device Token指向同一臺(tái)設(shè)備的同一個(gè)app台妆,又把多個(gè)device Token發(fā)給APNs時(shí)切厘,用戶就會(huì)收到多條push疫稿。蘋果APNs是不會(huì)對(duì)多個(gè)device Token是否指向同一臺(tái)設(shè)備的同一個(gè)app做校驗(yàn)的靶壮,所以需要后臺(tái)來(lái)做去重等處理保證用戶不會(huì)收到多條push腾降。
? ?? ???5.3 對(duì)離線(遠(yuǎn)程)push的響應(yīng)
1)iOS 7以上對(duì)離線(遠(yuǎn)程)push時(shí)的響應(yīng)
? ?? ???iOS 7以上關(guān)于接受離線push有兩個(gè)函數(shù):
? ?? ???那么這兩個(gè)函數(shù)有什么區(qū)別呢?其實(shí)這兩個(gè)方法都是用來(lái)處理離線push的奸晴。
? ?? ???差別就是,如果app在前臺(tái)是收到離線(遠(yuǎn)程)push墩划,那么就會(huì)調(diào)用:
? ?? ???相對(duì)的,如果在后臺(tái)或者殺進(jìn)程情況下察净,點(diǎn)擊收到的離線push氢卡,那么就會(huì)調(diào)用译秦,如果沒(méi)有實(shí)現(xiàn):
? ?? ???則會(huì)調(diào)用:
? ?? ???若實(shí)現(xiàn)了前者延都,就只調(diào)用前者求摇。
2)iOS 10以上對(duì)離線(遠(yuǎn)程)push的響應(yīng)
? ?? ???iOS10對(duì)push的處理主要增加了兩個(gè)方法:
? ?? ???其中前者是對(duì)APP在前臺(tái)時(shí)收到push時(shí)的處理与境,后者是點(diǎn)擊push進(jìn)入APP執(zhí)行的函數(shù)挥转。
? ?? ???用得比較多的是后者绑谣,我們可以舉個(gè)例子,點(diǎn)擊push進(jìn)入APP后如何獲取push的消息壤玫、角標(biāo)欲间、標(biāo)題等內(nèi)容:
? ?? ???6腻豌、iOS 10關(guān)于push的一些新特性
? ?? ???iOS10新增的UserNotifications框架吝梅,主要有了這樣幾方面的更新:
? ?? ???1)用UserNotifications框架替換了原先與通知相關(guān)的接口做瞪,通知文字可分為title装蓬、subtitle和body三部分牍帚,通知可攜帶附件鄙币;
? ?? ???2)系統(tǒng)在展示通知之前十嘿,可以喚起app附帶的service extension,并且允許它改動(dòng)通知的內(nèi)容唇聘;
? ?? ???3)用戶在對(duì)通知右滑查看迟郎、下拉或者3d touch的時(shí)候宪肖,通知會(huì)展開(kāi),展開(kāi)后頁(yè)面的布局可以由app附帶的content extension來(lái)決定蜕衡。
? ?? ???6.1 push的多樣性
? ?? ???iOS10以前的push只有文字慨仿,甚至沒(méi)有標(biāo)題。iOS10以后的push更加多樣化万皿,可以有主標(biāo)題牢硅,副標(biāo)題减余,甚至還有附件休里。
? ?? ???這里以我司的騰訊新聞為例(有標(biāo)題妙黍,內(nèi)容,和附件):
? ?? ???3D touch點(diǎn)入詳情以后:
? ?? ???這里我們驚奇的發(fā)現(xiàn)做粤,除了可以攜帶圖片這樣的附件、push還能展開(kāi)詳情以外肉康,進(jìn)入詳情以后吼和,下面還多了“打開(kāi)”、“收藏”末捣、“不感興趣”這些選項(xiàng)塔粒,這里就涉及到以下iOS10的新特性。
? ?? ???6.2 push攜帶附件
? ?? ???因?yàn)閜ayload有大小限制咖熟,所以如果remote notification想要攜帶附件馍管,那么payload上只能帶上如附件下載地址之類的信息捌锭,等通知到達(dá)客戶端后由service extension下載附件到本地观谦,然后在初始化UNNotificationAttachment對(duì)象時(shí)傳入附件在本地的URL豁状。
? ?? ???初始化UNNotificationAttachment對(duì)象時(shí),可以傳入option參數(shù)谊路。這里的option參數(shù)可以強(qiáng)制指定附件的類型凶异,可以選擇是否展示縮略圖,以及縮略圖截取自附件的哪一幀喉恋、哪一部分轻黑。
? ?? ???目前iOS10通知只將幾種格式的圖片、音頻和視頻作為附件抖拦,附件的大小也有一定限制态罪,具體可以看官方文檔中的限制說(shuō)明。
? ?? ???關(guān)于附件的更加詳細(xì)的說(shuō)明耗啦,可以參考官方文檔:點(diǎn)此進(jìn)入帜讲。
? ?? ???6.3 攜帶action的通知
? ?? ???上面提到的“打開(kāi)”舒帮、“收藏”肢执、“不感興趣”這些選項(xiàng)其實(shí)就是push攜帶的action预茄,其實(shí)從iOS8開(kāi)始耻陕,通知已經(jīng)可以攜帶action了。而在iOS10中想诅,通知的action被放在了更明顯的位置篮灼,與action相關(guān)的接口也有了很大變化诅诱。
? ?? ???決定一個(gè)通知應(yīng)該有哪些action呢娘荡?在payload中,這是由category字段決定的商乎。如果我們希望一個(gè)通知能攜帶若干個(gè)action鲜戒,我們就需要將若干個(gè)action和一個(gè)category綁定起來(lái)遏餐。通知到達(dá)前端后失都,系統(tǒng)會(huì)根據(jù)category的名字來(lái)決定要給這個(gè)通知展示哪些action:
? ?? ???怎么得知用戶選了哪個(gè)action并做出相應(yīng)操作呢洽损?這需要給UNUserNotificationCenter指定一個(gè)delegate:
? ?? ???然后在delegate的類中實(shí)現(xiàn):
? ?? ???方法:通過(guò)response.notification.request.content.categoryIdentifier和response.actionIdentifier就可以得知用戶選擇的action了流码。
? ?? ???6.4 改變push內(nèi)容
? ?? ???這里主要講應(yīng)用的比較多的離線(遠(yuǎn)程)push的改變push方法谴蔑。
1)改變本地push內(nèi)容:
? ?? ???本地push秘车,只要request的id一樣叮趴,那么就可以更新推送眯亦。
? ?? ???更新的例子:
? ?? ???此外,還有刪除所有推送等宫静,都在UNUserNotificationCenter.h中實(shí)現(xiàn)伏伯。
2)改變離線(遠(yuǎn)程)push內(nèi)容:
? ?? ???目前遠(yuǎn)程push只支持更新push內(nèi)容说搅,更新需要通過(guò)新的字段apps-collapse-id來(lái)作為唯一標(biāo)示弄唧。方法是在HTTP/2 請(qǐng)求頭中使用相同的apns-collapse-id,這樣收到同樣的apns-collapse-id的push時(shí)背伴,push內(nèi)容便會(huì)更新傻寂。
使用場(chǎng)景:比較容易理解的一個(gè)場(chǎng)景就是球賽比分,比如現(xiàn)在是1:0徐紧,如果變成1:1的話拂檩,只需要刷新原來(lái)的新聞稻励,這樣用戶就不會(huì)因?yàn)橥粓?chǎng)比賽收到多條push。
? ?? ???6.5 兩個(gè)extension
? ?? ???有兩個(gè)與push相關(guān)的extension煤篙,可能我們會(huì)好奇這兩個(gè)extension有什么不同苛茂,為什么需要兩個(gè)味悄?它們分別實(shí)現(xiàn)什么功能呢?
【1)notification service extension】
? ?? ???給app添加notification service extension后,系統(tǒng)會(huì)在收到通知后喚醒它茧球,并允許它修改通知的內(nèi)容抢埋,之后再展示這個(gè)通知揪垄。
? ?? ???service extension只對(duì)remote notification起作用,local notification是無(wú)法喚起它的八回。
? ?? ???如果想要讓系統(tǒng)喚起service extension的話酷愧,payload必須符合這樣幾個(gè)條件:
? ?? ???1)必須增加mutable-content字段并為1,這表示允許客戶端修改這個(gè)通知:
? ?? ???payload(舉例)如下:
? ?? ???2)這個(gè)通知必須展示一個(gè)alert缠诅,如果只是一個(gè)修改badge的通知的話溶浴,是不會(huì)喚起service extension的
? ?? ???3)靜默推送是不能喚起service extension的,所以payload中不能有”content-available” : 1字段管引。
? ?? ???所以士败,通過(guò)這個(gè)notification service extension,你可以在接收到推送之后、展示推送之前處理一些事情伤锚,比如說(shuō)更新一下推送內(nèi)容,或者在后臺(tái)做一些其他事情。
【2)notification content extension】
? ?? ???另一項(xiàng)notification content extension用于完全自定義推送展開(kāi)后的視圖态鳖。上面騰訊新聞的展開(kāi)后的視圖就是通過(guò)這個(gè)notification content extension實(shí)現(xiàn)的邦泄。
? ?? ???依然以騰訊新聞為例子:
? ?? ???這里Notification Content Extension大展拳腳的地方,在這里可以自定義繪制不同的內(nèi)容硅瞧,將希望展現(xiàn)給用戶的額外信息可以加載這里颂暇。
? ?? ???下半部分的notification action的實(shí)現(xiàn)就是在上面提到的“攜帶action的通知”阳啥。
7卷拘、iOS Push的測(cè)試要點(diǎn)羅列
? ?? ???另外注意一點(diǎn):測(cè)試Push的時(shí)候瓣蛀,區(qū)分好Appstore證書(shū)和開(kāi)發(fā)證書(shū)林束。兩者不能相互發(fā)Push。
8宵睦、有關(guān)iOS Push的常見(jiàn)疑問(wèn)匯總
? ?? ???Q:離線push酵使,支持角標(biāo)(badge)在本地角標(biāo)數(shù)值上+1這樣的操作嗎?
? ?? ???A:不支持。如果是自己實(shí)現(xiàn)push服務(wù)的話,需要自己的后臺(tái)將角標(biāo)值badge發(fā)送個(gè)APNs服務(wù)器太伊,有些APP使用第三方push SDK除外赛不。
? ?? ???Q:如果重復(fù)收到離線push,可能是什么情況伙窃?
? ?? ???A:
? ?? ???1)iOS9之后卸載重裝后生成新的deviceToken声滥,后臺(tái)對(duì)多個(gè)deviceToken都發(fā)送了push
? ?? ???2)后臺(tái)對(duì)注銷了的賬號(hào)也發(fā)送了push错蝴。
? ?? ???總而言之一般是后臺(tái)的邏輯出現(xiàn)了問(wèn)題床玻,而不是APNs服務(wù)器出現(xiàn)問(wèn)題茄蚯。
? ?? ???Q:直接卸載APP,還能收到離線push嗎都办?
? ?? ???A:不會(huì)收到躲庄。直接卸載APP谱秽,雖然后臺(tái)不知道APP被卸載了疯淫,仍然會(huì)對(duì)之前的賬號(hào)發(fā)送push,但是由于手機(jī)上沒(méi)有對(duì)應(yīng)APP,所以并不會(huì)收到push笛臣。
? ?? ???Q:為什么有時(shí)候全新安裝APP就立馬有紅點(diǎn)角標(biāo)猬膨?
? ?? ???A:這是因?yàn)樾遁d該APP時(shí)有紅點(diǎn)角標(biāo)著觉。每個(gè) APP 的角標(biāo)都是存在 iOS 手機(jī)系統(tǒng)里的肄鸽,開(kāi)發(fā)無(wú)法修改,所以此時(shí)卸載前有角標(biāo),重新安裝也會(huì)有角標(biāo)抛腕。但是刹悴,APP 卸載之后超過(guò)一天的時(shí)間再重裝李茫,那么角標(biāo)就會(huì)被系統(tǒng)清空揭保,屆時(shí)也不會(huì)有新安裝的 APP 就有角標(biāo)的情況存在。
? ?? ???Q:自己Server通過(guò)APNs發(fā)的每一條Push魄宏,客戶端都會(huì)收到么秸侣?
? ?? ???答案是否定的,Push是不可靠的,push通知是fire-and-forget味榛,比如手機(jī)關(guān)機(jī)椭坚,那么自然就收不到,雖然Apple會(huì)嘗試幾次搏色。
? ?? ???Q:Push消息的大小是多少善茎?
? ?? ???iOS8發(fā)的時(shí)間點(diǎn)起,無(wú)論那個(gè)iOS系統(tǒng)频轿,push消息的body大小調(diào)整為2k垂涯,注意這里是iOS8的時(shí)間點(diǎn),也就是2014年秋航邢,就目前來(lái)說(shuō)push的限制應(yīng)該是2k不再是256了耕赘。
9、相關(guān)工具推薦
? ?? ???Knuff離線push工具下載鏈接:http://github.com/KnuffApp/Knuff/releases
? ?? ???使用方法也比較簡(jiǎn)單:
? ?? ???比如我的payload輸入如下:
? ?? ???得到的應(yīng)該是有“Knuff測(cè)試”文字膳殷,和角標(biāo)數(shù)變?yōu)?99操骡,我們可以看下結(jié)果,與預(yù)料是一致的:
? ?? ???有了這個(gè)工具也更加方便了我們的iOS push的調(diào)試赚窃。
附錄:更多消息推送技術(shù)文章
? ?? ???《iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路册招、技術(shù)原理及缺陷等》
? ?? ???《信鴿團(tuán)隊(duì)原創(chuàng):一起走過(guò) iOS10 上消息推送(APNS)的坑》
? ?? ???《Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳笨颊ィ活跨细、遇到的問(wèn)題等》
? ?? ???《掃盲貼:認(rèn)識(shí)MQTT通信協(xié)議》
? ?? ???《一個(gè)基于MQTT通信協(xié)議的完整Android推送Demo》
? ?? ???《IBM技術(shù)經(jīng)理訪談:MQTT協(xié)議的制定歷程、發(fā)展現(xiàn)狀等》
? ?? ???《求教android消息推送:GCM河质、XMPP冀惭、MQTT三種方案的優(yōu)劣》
? ?? ???《移動(dòng)端實(shí)時(shí)消息推送技術(shù)淺析》
? ?? ???《掃盲貼:淺談iOS和Android后臺(tái)實(shí)時(shí)消息推送的原理和區(qū)別》
? ?? ???《絕對(duì)干貨:基于Netty實(shí)現(xiàn)海量接入的推送服務(wù)技術(shù)要點(diǎn)》
? ?? ???《移動(dòng)端IM實(shí)踐:谷歌消息推送服務(wù)(GCM)研究(來(lái)自微信)》
? ?? ???《為何微信、QQ這樣的IM工具不使用GCM服務(wù)推送消息掀鹅?》
? ?? ???《極光推送系統(tǒng)大規(guī)模高并發(fā)架構(gòu)的技術(shù)實(shí)踐分享》
? ?? ???《從HTTP到MQTT:一個(gè)基于位置服務(wù)的APP數(shù)據(jù)通信實(shí)踐概述》
? ?? ???《魅族2500萬(wàn)長(zhǎng)連接的實(shí)時(shí)消息推送架構(gòu)的技術(shù)實(shí)踐分享》
? ?? ???《專訪魅族架構(gòu)師:海量長(zhǎng)連接的實(shí)時(shí)消息推送系統(tǒng)的心得體會(huì)》
? ?? ???《深入的聊聊Android消息推送這件小事》
? ?? ???《基于WebSocket實(shí)現(xiàn)Hybrid移動(dòng)應(yīng)用的消息推送實(shí)踐(含代碼示例)》
? ?? ???《一個(gè)基于長(zhǎng)連接的安全可擴(kuò)展的訂閱/推送服務(wù)實(shí)現(xiàn)思路》
? ?? ???《實(shí)踐分享:如何構(gòu)建一套高可用的移動(dòng)端消息推送系統(tǒng)散休?》
? ?? ???《Go語(yǔ)言構(gòu)建千萬(wàn)級(jí)在線的高并發(fā)消息推送系統(tǒng)實(shí)踐(來(lái)自360公司)》
? ?? ???《騰訊信鴿技術(shù)分享:百億級(jí)實(shí)時(shí)消息推送的實(shí)戰(zhàn)經(jīng)驗(yàn)》
? ?? ???《百萬(wàn)在線的美拍直播彈幕系統(tǒng)的實(shí)時(shí)推送技術(shù)實(shí)踐之路》
? ?? ???《京東京麥商家開(kāi)放平臺(tái)的消息推送架構(gòu)演進(jìn)之路》
? ?? ???《了解iOS消息推送一文就夠:史上最全iOS Push技術(shù)詳解》
本文轉(zhuǎn)載自coca4app_手工藝人:了解iOS消息推送一文就夠:史上最全iOS Push技術(shù)詳解