推送-推送原理性說明

前言

我們在實現推送功能的時候,更需要了解下推送的原理機制,這樣我們在發現問題時候才好定位到問題的解決辦法。

推送流程和原理

推送
推送

Provider就是我們自己程序的后臺服務器(或者是第三方的推送服務器),APNS是Apple Push Notification Service的縮寫,也就是蘋果的推送服務器。
上圖可以分為三個階段:

  • 第一階段:應用程序的服務器端把要發送的消息、目的iPhone的標識打包,發給APNS。
  • 第二階段:APNS在自身的已注冊Push服務的iPhone列表中,查找有相應標識的iPhone,并把消息發送到iPhone。
  • 第三階段:iPhone把發來的消息傳遞給相應的應用程序,并且按照設定彈出Push通知。

APNS推送通知的詳細工作流程下面這張圖是說明APNS推送通知的詳細工作流程:

根據圖片我們可以概括一下:

  • 應用程序注冊APNS消息推送。
  • iOS從APNS Server獲取devicetoken,應用程序接收device token。
  • 應用程序將device token發送給程序的PUSH服務端程序。
  • 服務端程序向APNS服務發送消息。
  • APNS服務將消息發送給iPhone應用程序。

有幾點值得注意

  • 首先要有一臺蘋果的設備,模擬器是不支持推送的,

  • APNS
    如果需要給應用集成推送功能,就一定要用到蘋果的推送服務。Apple推送通知服務(Apple Push Notification service =APNs),例如友盟,極光之類的推送服務都是向APNs推送消息,APNs再將消息推送給設備的。

  • 推送消息傳輸路徑:
    Provider-APNs-Client App 我們的設備聯網時(無論是蜂窩聯網還是Wi-Fi聯網)都會與蘋果的APNs服務器建立一個長連接(persistent IP connection),當Provider推送一條通知的時候,這條通知并不是直接推送給了我們的設備,而是先推送到蘋果的APNs服務器上面,而蘋果的APNs服務器再通過與設備建立的長連接進而把通知推送到我們的設備上(參考圖1-1,圖1-2)。而當設備處于非聯網狀態的時候,APNs服務器會保留Provider所推送的最后一條通知,當設備轉換為連網狀態時,APNs則把其保留的最后一條通知推送給我們的設備;如果設備長時間處于非聯網狀態下,那么APNs服務器為其保存的最后一條通知也會丟失。Remote Notification必須要求設備連網狀態下才能收到,并且太頻繁的接收遠程推送通知對設備的電池壽命是有一定的影響的。

  • deviceToken的生成
    當一個App注冊接收遠程通知時,系統會發送請求到APNs服務器,APNs服務器收到此請求會根據請求所帶的key值生成一個獨一無二的value值也就是所謂的deviceToken,而后APNs服務器會把此deviceToken包裝成一個NSData對象發送到對應請求的App上。然后App把此deviceToken發送給我們自己的服務器,就是所謂的Provider。Provider收到deviceToken以后進行儲存等相關處理,以后Provider給我們的設備推送通知的時候,必須包含此deviceToken。

  • deviceToken到底是什么?有什么用?為什么是獨一無二的?

    是什么:deviceToken其實就是根據注冊遠程通知的時候向APNs服務器發送的Token key,Token key中包含了設備的UDID和App的Bundle Identifier,然后蘋果APNs服務器根據此Token key編碼生成一個deviceToken。deviceToken可以簡單理解為就是包含了設備信息和應用信息的一串編碼。

    有什么用:上面提到Provider推送消息的時候必須帶有此deviceToken,然后此消息就根據deviceToken(UDID + App's Bundle Identifier)找到對應的設備以及該設備上對應的應用,從而把此推送消息推送給此應用。

    唯一性:蘋果APNs的編碼技術和deviceToken的獨特作用保證了他的唯一性。唯一性并不是說一臺設備上的一個應用程序永遠只有一個deviceToken,當用戶升級系統的時候deviceToken是會變化的。

  • 后臺推送也是很必須的,不是所謂的多做活動,因為有些推送是條件觸發的,無法做到人為推送(比如大量用戶中,接單后通知發單的人)。

  • 推送通知本身是 iOS 系統的行為,所以在 App 沒有運行(沒有在前臺也沒有在后臺)的時候:仍然能夠推送及接收(通知中心通知、頂部橫幅、刷新 App 右上角的小圓點即 badge [以下簡稱角標] 等都會由系統來控制和展示)。但是收到推送時,是無法在 App 的代碼中獲取到通知內容的。因為沙盒機制,此時 App 的任何代碼都不可能被執行。

開發中實現推送的步驟

  • 在代碼中注冊推送服務;

  • 在第一次觸發這段代碼的時候,會有一個系統彈窗,詢問你是否允許該 App 要給你推送信息。當你選擇允許時,系統會打包 App+手機唯一標識+證書 信息發送至 APNs 服務器注冊推送服務,APNs 系統會對該手機安裝的該 App 是否有推送權限進行驗證,所以必須要加入了 Apple Deveice 的手機,使用對應 App 的推送證書才能夠成功的注冊。

  • 如果注冊成功,則可以在 AppDelegate.m 的如下方法中獲取到 deviceToken,它是對 該手機+該App 組合的一個唯一標識,當使用遠程推送時,只需將推送消息發給指定的 deviceToken 即可使推送信息傳達給指定手機的指定 App 上。因此如果你使用第三方,就需要在這個方法里將 deviceToken 傳給第三方。(在 iOS 9 為了更好的保護用戶隱私,會出現多次重復刪除/安裝 App 導致 deviceToken 不斷變化的情況。有時會出現一條推送手機會收到 2 次的問題,屬于 iOS 9 系統問題)。

     -(void)application:(UIApplication *)application   didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {  
       [JPUSHService registerDeviceToken:deviceToken];//將 deviceToken 傳給極光推送
     }
    
  • 綜上,注冊及接收推送 必須 使用真機,必須連網。

推送從 服務端 --> App 代碼 的過程

  • 使用你們公司或第三方的服務端向 APNs 發送推送請求(包含 推送內容+App描述+手機描述 )
  • APNs 接收并驗證推送請求
  • APNs 利用網絡搜索并定位指定設備,下發推送
  • 手機收到推送,系統根據 App 狀態進行處理
    前臺收到:
    后臺收到:
    退出收到:

推送分幾種分類

  • 普通式推送

    就是我們在手機上平時見到的推送
    包含聲音、彈窗、角標、自定義字段

      App      
          處于前臺:不會彈窗,可通過 didReceiveRemoteNotification 獲取推送內容([前臺彈窗的方法看這里](https://github.com/pikacode/EBForeNotification))
          處于后臺:會彈窗 ,無法獲取推送內容
          處于退出: 會彈窗,無法獲取推送內容,點擊圖標啟動,無法獲取推送內容
          點擊推送彈窗啟動,在 didFinishLaunchingWithOptions獲取推送內容
    
      推送內容類似如下:
    
      {
          "_j_msgid" = 200806057;//第三方附帶的 id,用于在后臺查詢送達情況  
          aps =     {
              alert = "顯示內容";
            badge = 1;//App 角標,可推送 n、+n、-n 來實現角標的固定、增加、減少
            sound = default;//推送聲音,默認系統三全音,如需使用自己的聲音,需要將聲音文件拖拽&拷貝至 Xcode 工程目錄任意位置,并在推送時指定其文件名
          };
          key1 = value1;//自定義字段,可設置多組,用于處理內部邏輯 
          key2 = value2;
      }
    
  • 后臺式推送

    各種顯示效果跟普通推送完全一樣。
    必須攜帶alert、badge、sound中至少 1 個字段。
    僅 iOS 7 以后支持。
    必須在 Xcode 工程中 TARGETS - Capabilities - Background Modes - Remote notifications 開啟該功能.

     App:
          處于前臺:可通過didReceiveRemoteNotification(iOS 7 before)didReceiveRemoteNotification:fetchCompletionHandler:(iOS 7 after) 獲取通知內容。
          處于后臺:可通過didReceiveRemoteNotification:fetchCompletionHandler:獲取通知內容 // 獲取情況中與普通推送的唯一不同點,此時 iOS 系統允許開發者在 App 處于后臺的情況下,執行一些代碼,大概提供幾分鐘的時間,可以用來偷偷的刷新 UI、切換頁面、下載更新包等等操作。
          處于退出:無法獲取通知內容。
        點擊圖標啟動,無法獲取通知內容。
        點擊推送橫幅啟動,在didFinishLaunchingWithOptions獲取通知內容。
    
      通知內容類似如下:
      { 
            "_j_msgid" = 2090737306;
           aps = {
                alert = "顯示內容"; 
               badge = 1; 
            }; 
         key1 = value1;
      }
    
  • 靜默式推送

    沒有任何展示效果。
    必須攜帶 "content-available" = 1;,因此靜默必然是后臺的。
    必須不攜帶 alert、badge、sound。
    可攜帶自定義字段。

    App :
      處于前臺:可通過didReceiveRemoteNotification(iOS 7 before)didReceiveRemoteNotification:fetchCompletionHandler:(iOS 7 after) 獲取通知內容。
      處于后臺:可通過 didReceiveRemoteNotification:fetchCompletionHandler: 獲取通知內容 //獲取情況中與普通推送的唯一不同點,此時 iOS 系統允許開發者在 App 處于后臺的情況下,執行一些代碼,大概提供幾分鐘的時間,可以用來偷偷的刷新 UI、切換頁面、下載更新包等等操作。
      處于退出,無法獲取通知內容。
      通知內容類似如下:
    {
         "_j_msgid" = 3938587719;
         aps =     {
             alert = "";
            "content-available" = 1;  // 必帶字段
         };
         key1 = value1;
      }
    

小結

推送的大致原理我們說了一下,其他相關知識可以查看我的其他相關知識。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容