[iOS]APNs推送機(jī)制


目錄

一、簡介
二、APNs推送流程
三、什么是deviceToken
四、消息體
五、APNs推送中的問題


APNs 簡介

Apple Push Notification service (APNs),即蘋果推送通知服務(wù)。

為什么會(huì)有 APNs ?

由于移動(dòng)設(shè)備內(nèi)存、CPU、電量的局限性,iOS 不允許 APP 的進(jìn)程常駐后臺(tái)(事實(shí)上可以申請(qǐng)后臺(tái)運(yùn)行一段時(shí)間,最長約10分鐘)。

當(dāng)用戶主動(dòng)殺掉APP或者APP進(jìn)入后臺(tái)超過限定時(shí)長時(shí),就意味著該APP進(jìn)程的結(jié)束。這很大程度保障了前臺(tái)APP的流暢性,也延長了手機(jī)的使用時(shí)長。這也是蘋果用戶體驗(yàn)好的原因之一。但是這也意味著,服務(wù)器無法主動(dòng)和用戶交互(如推送實(shí)時(shí)消息等)。為了解決這個(gè)限制,蘋果推出了APNs,允許設(shè)備和服務(wù)器分別與蘋果的推送通知服務(wù)器保持長連接狀態(tài)。

iOS的通知

iOS分本地通知和遠(yuǎn)程通知,(APNs)是遠(yuǎn)程通知功能的核心.

  • 本地通知是由本地應(yīng)用觸發(fā)的。一般是基于時(shí)間的一種通知形式,如鬧鐘、待辦事件等的提醒。
  • 遠(yuǎn)程通知是通過我們自己的服務(wù)器推送消息的一種通知形式。

APNs推送流程

假如我們的蘋果設(shè)備(AC電腦、筆記本、iPad、iPhone等)安裝了一個(gè)名叫XXX的應(yīng)用。那么我們具體是怎樣接收到推送通知的那??接下來我們就說說具體這個(gè)過程。下面是蘋果APNs官方簡介 中提供的APNs推送流程的圖

APNs_img1.png
Provier 代表我們自己的應(yīng)用服務(wù)器
APNs 代表蘋果的APNs推送服務(wù)器
接著是代表的就是蘋果的設(shè)備
Client App 代表我們開發(fā)的應(yīng)用

說明:

    1. 安裝了XXX應(yīng)用的蘋果設(shè)備需要向APNs服務(wù)器注冊(cè),注冊(cè)成功后APNs服務(wù)器會(huì)返回一個(gè)deviceToken,并且二者之間會(huì)維持一個(gè)長連接(這個(gè)長連接是基于SSL協(xié)議的TCP流通訊)
    1. 拿到這個(gè)deviceToken后我們將這個(gè)deviceToken發(fā)給我們自己的服務(wù)器
    1. 當(dāng)有消息需要被推送時(shí),我們自己的服務(wù)器會(huì)將消息按指定的格式結(jié)合設(shè)備的deviceToken一并打包 然后發(fā)給APNs服務(wù)器
    1. APNs將新消息推送給我們的設(shè)備上,然后就在設(shè)備的屏幕上顯示出來了 (因?yàn)槲覀兊脑O(shè)備和APNs服務(wù)器二者之間維持了一個(gè)長連接)

注意說明:
真正完成推送的是APNS服務(wù)器。消息一定是由APNs服務(wù)器推送給我們的設(shè)備的,我們自己的應(yīng)用服務(wù)器只是將需要推送的消息告訴APNs服務(wù)器。至于如何維護(hù)消息隊(duì)列或如何保證消息能被推送到指定的設(shè)備上,這些都由蘋果APNs做好的。

什么是deviceToken ?

deviceToken是一個(gè)APP裝在一個(gè)設(shè)備上的唯一標(biāo)識(shí)符。一個(gè)APP在不同的設(shè)備上deviceToken不一樣;一個(gè)APP刪除之后再次安裝deviceToken也不一樣。

在項(xiàng)目代碼AppDelegate里面有一個(gè)回調(diào)方法,當(dāng)APNs注冊(cè)成功通過該回調(diào)方法可以獲取到返回的deviceToken

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

上面說過當(dāng)有消息需要被推送時(shí),我們自己的服務(wù)器會(huì)將消息按指定的格式結(jié)合設(shè)備的deviceToken一并打包 ,APNs拿到這個(gè)包之后驗(yàn)證這個(gè)包結(jié)構(gòu)是否正確并提取其中的信息后,再將消息推送到指定的設(shè)備。

接下來就來看看這個(gè)包的結(jié)構(gòu):

APNs_img2.jpg

這個(gè)包分五個(gè)部分

  • 第一個(gè)部分是命令標(biāo)示符
  • 第二個(gè)部分是我們的deviceToken的長度
  • 第三個(gè)部分是我們的deviceToken字符串
  • 第四個(gè)部分是推送的消息體(Payload)的長度
  • 最后一個(gè)部分也就是真正的消息內(nèi)容了,里面包含了推送消息的基本信息。(比如消息內(nèi)容,應(yīng)用icon右上角顯示的數(shù)字角標(biāo)以及推送消息到達(dá)時(shí)所播放的聲音等)

接下來詳細(xì)看一下Payload(消息體)的結(jié)構(gòu)

APNs_img3.png

Payload(消息體)其實(shí)就是個(gè)JSON結(jié)構(gòu)體。上面的圖只是簡單的一種消息體更多詳細(xì)類型的消息體類型,請(qǐng)看消息體蘋果官方相關(guān)介紹

  • alert里的就是會(huì)顯示在用戶手機(jī)上的推送標(biāo)題內(nèi)容
  • badge顯示的數(shù)量(注意是整型)是會(huì)在應(yīng)用icon右上角顯示的數(shù)量,提示有多少條未讀消息等
  • sound就是當(dāng)推送信息送達(dá)是手機(jī)播放的聲音,傳defalut就標(biāo)明使用系統(tǒng)默認(rèn)聲音,如果傳比如“xxx.wav”就會(huì)播放在我們應(yīng)用工程目錄下名稱為xxx.wav的音頻文件,比如當(dāng)手機(jī)鎖屏?xí)rQQ在后臺(tái)收到新消息時(shí)的滴滴聲。

安全架構(gòu)

為了保證安全性,APNs用連接信任(connection trust)和token信任(token trust)來控制通信入口,你要用APNs則必須用通過這兩種驗(yàn)證。

連接信任

連接信任第一個(gè)作用是保證APNs連接的provider是蘋果已經(jīng)同意可通信的,然后第二個(gè)是保證與APNs連接的設(shè)備的合法性,第二步是APNs處理的,你所要處理的是provider與APNs之間的連接安全性。

服務(wù)器與APNs之間的連接信任
每個(gè)服務(wù)器都必須要有唯一的provider證書和私鑰,都是用來驗(yàn)證連接的。provider證書就是在開發(fā)者官網(wǎng)申請(qǐng)的。

服務(wù)器通過TLS驗(yàn)證和APNs連接,HTTPS中用的也是TLS協(xié)議,即四步握手,首先初始化TLS連接,即provider(服務(wù)器)發(fā)送請(qǐng)求給APNs,APNs服務(wù)器返回APNs證書(即公鑰)給provider,然后服務(wù)端收到后生成provider證書后再返回給APNs,APNs收到后驗(yàn)證后即可以建立TLS連接,不過APNs用的不是HTTPS,而是HTTP/2,具體過程如下圖

APNs推送中的問題

問題一: 當(dāng)應(yīng)用從設(shè)備卸載后,推送的消息改如何處理??

我們知道當(dāng)應(yīng)用從設(shè)備卸載后,是收不到推送消息的。但是,如何讓APNs和Provider知道不再向這臺(tái)卸載了應(yīng)用的設(shè)備推送消息呢?

針對(duì)這個(gè)問題蘋果也已經(jīng)幫我們解決了(那就是Feedback Service)。它是APNS的一部分,APNs會(huì)持續(xù)的更新Feedback service的列表,當(dāng)我們的Provider將信息發(fā)給APNs服務(wù)器,APNs推送信息到我們的設(shè)備時(shí),如果這時(shí)設(shè)備無法將消息推送到指定的應(yīng)用(應(yīng)用已經(jīng)刪除),就會(huì)向APNs服務(wù)器發(fā)送一個(gè)反饋信息,而這個(gè)信息就記錄在Feedback service中。按照這種方式,Provider應(yīng)該定時(shí)的去檢測Feedback service的列表,然后刪除在自己數(shù)據(jù)庫中記錄的存在于反饋列表中的deviceToken,從而不再向這些設(shè)備發(fā)送推送信息。連接Feedback service的過程同樣使用長連接的方式,連接上后,直接接收由APNs傳輸給我們的反饋列表,傳輸完成后斷開連接,然后我們根據(jù)這個(gè)最新的反饋列表在更新我們自己的數(shù)據(jù)庫,刪除那些不再需要推送信息的設(shè)備的deviceToken。

從Feedback service讀取的數(shù)據(jù)結(jié)構(gòu)如下:

從Feedback service讀取的數(shù)據(jù)結(jié)構(gòu)

結(jié)構(gòu)中包含三個(gè)部分

  • 第一部分是一個(gè)時(shí)間戳,記錄的是設(shè)備失效后的時(shí)間信息
  • 第二個(gè)部分是deviceToken的長度
  • 第三部分就是失效的deviceToken,我們所要獲取的就是第三部分,跟我們的數(shù)據(jù)庫進(jìn)行對(duì)比后,刪除對(duì)應(yīng)的deviceToken,下次不再向這些設(shè)備發(fā)送推送信息

問題二:iOS 重復(fù)推送之謎 文章地址

問題三:收不到 APNs 推送怎么辦?

  • 首先要知道服務(wù)器推送成功,并不代表設(shè)備就能收到推送。服務(wù)器推送成功只是將消息交給了蘋果服務(wù)器而已,蘋果服務(wù)器還需要設(shè)備在線才能推送的。
  • 其次 deviceToken 可能會(huì)在 APP 卸載重裝后發(fā)生變化,客戶端對(duì)此需要制定相應(yīng)的匯報(bào)策略,以便服務(wù)器及時(shí)更新存儲(chǔ)的 deviceToken 。
    客戶端只要能上報(bào)正確的 deviceToken 就可以說明客戶端實(shí)現(xiàn)沒問題了。否則檢查客戶端是否開啟了遠(yuǎn)程推送通知服務(wù),Bundle Identifier 是否與申請(qǐng)的推送證書匹配。
  • 檢查服務(wù)器內(nèi)存緩存的 deviceToken 或者數(shù)據(jù)庫存儲(chǔ)的 deviceToken 是否與客戶端匯報(bào)的一致。
    排查服務(wù)器配置的證書是否過期,是否與客戶端的 Bundle Identifier 匹配,或者是否勿用了其他類型的推送證書。
    采用抓包工具(如 Wireshark )抓包分析,看看服務(wù)器是否將消息交給蘋果服務(wù)器,客戶端是否收到了相應(yīng)的推送通知。

參考文檔:

國內(nèi) 90%以上的 iOS 開發(fā)者,對(duì) APNs 的認(rèn)識(shí)都是錯(cuò)的
iOS 必知必會(huì) - APNs篇
蘋果推送機(jī)制APNs(一)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 極光推送: 1.JPush當(dāng)前版本是1.8.2,其SDK的開發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,887評(píng)論 10 16
  • 項(xiàng)目背景: 之前做過iOS原生的遠(yuǎn)程推送,這次趁著公司的項(xiàng)目研究ionic項(xiàng)目推送,本想著兩天就可以完事,但是io...
    Gaizka閱讀 2,496評(píng)論 2 2
  • 注:此文只現(xiàn)在已經(jīng)不能適配iOS10了,iOS10推送采用了新的方法,做iOS9及以下的系統(tǒng)可讀此篇文章。 最近公...
    TIME_for閱讀 33,709評(píng)論 85 322
  • 前言 我們?cè)趯?shí)現(xiàn)推送功能的時(shí)候,更需要了解下推送的原理機(jī)制,這樣我們?cè)诎l(fā)現(xiàn)問題時(shí)候才好定位到問題的解決辦法。 推送...
    進(jìn)無盡閱讀 3,999評(píng)論 0 5
  • 最近一直在忙迎新、招新的事,一門心思撲在這上面,空閑的時(shí)候,本來計(jì)劃著要學(xué)習(xí),可是不知道有什么要學(xué)怎么學(xué),我的媽呀...
    文茵baby閱讀 171評(píng)論 0 0

友情鏈接更多精彩內(nèi)容