關(guān)于iOS的Push Notification的響應

在說Push Notification的響應之前,先來討論下iOS應用程序的狀態(tài),回調(diào)方法以及狀態(tài)切換

  1. 應用程序的狀態(tài)
狀態(tài) 說明 描述
Not Running 未運行 程序沒啟動
Inactive 未激活 程序在前臺運行,不過沒有接收到事件。在沒有事件處理情況下程序通常停留在這個狀態(tài)
Active 激活 程序在前臺運行而且接收到了事件。這也是前臺的一個正常的模式
Backgroud 后臺 程序在后臺而且能執(zhí)行代碼,大多數(shù)程序進入這個狀態(tài)后會在在這個狀態(tài)上停留一會。時間到之后會進入掛起狀態(tài)(Suspended)。有的程序經(jīng)過特殊的請求后可以長期處于Backgroud狀態(tài)
Suspended 掛起 程序在后臺不能執(zhí)行代碼。系統(tǒng)會自動把程序變成這個狀態(tài)而且不會發(fā)出通知。當掛起時,程序還是停留在內(nèi)存中的,當系統(tǒng)內(nèi)存低時,系統(tǒng)就把掛起的程序清除掉,為前臺程序提供更多的內(nèi)存。
  1. 回調(diào)方法

    • application:didFinishLaunchingWithOptions:
      - 本地通知:UIApplicationDidFinishLaunchingNotification
      - 觸發(fā)時機:程序啟動并進行初始化的時候后。
      - 適宜操作:這個階段應該進行根視圖的創(chuàng)建。
    • applicationDidBecomeActive:
      - 本地通知:UIApplicationDidBecomeActiveNotification
      - 觸發(fā)時機:程序進入前臺并處于活動狀態(tài)時調(diào)用。
      - 適宜操作:這個階段應該恢復UI狀態(tài)(例如游戲狀態(tài))。
    • applicationWillResignActive:
      - 本地通知:UIApplicationWillResignActiveNotification
      - 觸發(fā)時機:從活動狀態(tài)進入非活動狀態(tài)。
      - 適宜操作:這個階段應該保存UI狀態(tài)(例如游戲狀態(tài))。
    • applicationDidEnterBackground:
      - 本地通知:UIApplicationDidEnterBackgroundNotification
      - 觸發(fā)時機:程序進入后臺時調(diào)用。
      - 適宜操作:這個階段應該保存用戶數(shù)據(jù),釋放一些資源(例如釋放數(shù)據(jù)庫資源)。
    • applicationWillEnterForeground:
      - 本地通知:UIApplicationWillEnterForegroundNotification
      - 觸發(fā)時機:程序進入前臺,但是還沒有處于活動狀態(tài)時調(diào)用。
      - 適宜操作:這個階段應該恢復用戶數(shù)據(jù)。
    • applicationWillTerminate:
      - 本地通知:UIApplicationWillTerminateNotification
      - 觸發(fā)時機:程序被殺死時調(diào)用。
      - 適宜操作:這個階段應該進行釋放一些資源和保存用戶數(shù)據(jù)。
  2. 狀態(tài)切換

    • 啟動程序
      Not running =》Inactive =》Active
      • willFinishLaunchingWithOptions
      • didFinishLaunchingWithOptions
      • applicationDidBecomeActive
    • 按下home鍵
      Active =》Inactive =》Background =》(Suspended =》Not Running)
      • applicationWillResignActive
      • applicationDidEnterBackground
      • applicationWillTerminate:
    • 雙擊home鍵,再打開程序
      • applicationWillEnterForeground
      • applicationDidBecomeActive

言歸正傳,來說說Push Notification的響應。首先說iOS 10 之前?;卣{(diào)函數(shù)有兩個,分別是

  • application:didReceiveRemoteNotification:
  • application:didReceiveRemoteNotification:fetchCompletionHandler:

這兩個函數(shù)有什么區(qū)別呢?
簡單來說,iOS7以上,你只需要實現(xiàn)第二個函數(shù)即可。因為如果你兩個函數(shù)都實現(xiàn)的化,程序只會調(diào)用第二個。(相信現(xiàn)在也沒有什么iOS不支持iOS7了吧。)
具體的請參考蘋果文檔
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623117-application
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application

APP狀態(tài) 消息推送 用戶操作 是否觸發(fā)
Not Running 收到推送消息提示 點擊消息 YES
Not Running 收到推送消息提示 點擊APP NO
Background 收到推送消息提示 點擊消息 YES
Background 收到推送消息提示 點擊APP NO
Active 無推送消息提示 YES

那么什么情況下application: didReceiveRemoteNotification: fetchCompletionHandler: 會被觸發(fā)?

APP狀態(tài) 消息推送 用戶操作 是否觸發(fā)
Not Running 收到推送消息提示 點擊消息 YES
Not Running 收到推送消息提示 點擊APP NO
Background 收到推送消息提示 點擊消息 YES
Background 收到推送消息提示 點擊APP NO
Active 無推送消息提示 YES

結(jié)論:如果應用不在激活狀態(tài),點擊APP激活應用是不會觸發(fā)application:didReceiveRemoteNotification:fetchCompletionHandler函數(shù)的,只有點擊推送過來的消息,才會觸發(fā)函數(shù)調(diào)用。

此外,在iOS7之后,不需要再考慮在應用未啟動狀態(tài)下,接到推送消息,在application: didFinishLaunchingWithOptions:中獲取推送信息了。因為application:didReceiveRemoteNotification:fetchCompletionHandler在這種情況下會被調(diào)用。如果還繼續(xù)在application: didFinishLaunchingWithOptions:中做推送處理,那么就會出現(xiàn)重復。

再看iOS10的情況,iOS10提供了兩個delegate函數(shù),分別對應應用處于激活狀態(tài)和非激活狀態(tài)

  • userNotificationCenter:willPresentNotification:withCompletionHandler:
  • userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
APP狀態(tài) 消息推送 用戶操作 是否觸發(fā)
Not Running 收到推送消息提示 點擊消息 觸發(fā) didReceiveNotificationResponse
Not Running 收到推送消息提示 點擊APP NO
Background 收到推送消息提示 點擊消息 觸發(fā) didReceiveNotificationResponse
Background 收到推送消息提示 點擊APP NO
Active 可自定義 觸發(fā)willPresentNotification

觸發(fā)willPresentNotification可自定義是否彈出消息提示,此時,若點擊消息提示,則會調(diào)用didReceiveNotificationResponse。

綜上,正確處理badge更新的好時機

  • 程序不在前臺

    • 我們可以在applicationDidBecomeActive函數(shù)中從服務器獲取各個badge的信息,并進行UI更新。
    • application:didReceiveRemoteNotification:fetchCompletionHandler 和application:didReceiveRemoteNotification:fetchCompletionHandler函數(shù)內(nèi)僅處理對應頁面的跳轉(zhuǎn)。
  • 程序在前臺
    application:didReceiveRemoteNotification:fetchCompletionHandler 和userNotificationCenter:willPresentNotification:withCompletionHandler函數(shù)內(nèi)從服務器獲取各個badge的信息,并進行UI更新。但不需要做對應頁面的跳轉(zhuǎn)。不希望打斷用戶當前的行為。

參考: iOS應用程序生命周期(前后臺切換,應用的各種狀態(tài))詳解

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

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

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