2016-07-25 36 views
0

我知道,當推送通知到達設備上(並且應用程序未打開它)時,沒有辦法檢查(我可能會錯誤)。但是在我的應用程序中有一個這樣的情況,那就是必須知道通知已到達設備。
我在應用程序中有多個選項卡,其中2個根據推送通知具有徽章實施。所以基本上有兩種不同類型的推送通知在設備上推送通知到達(未收到)時,代理被調用

假設如果一種類型的通知到達設備和用戶選擇不看通知。這樣,一個特定標籤的徽章計數被遞增由1。但問題是,哪一個。因爲當時我打開了應用程序,我沒有那些通知類型已經到達的信息。或者更確切地說,哪個標籤徽章計數將被遞增。 所以簡而言之,我怎麼知道,通知已到達設備(未收到)?

+1

你可以在服務器的通知載荷中傳遞''badge「:count',不會那麼做嗎? –

+0

@BhumitMehta:問題是,在這種情況下,didReceiveRemoteNotification永遠不會從我們獲取有效負載的位置調用,因爲我沒有打開通知。 – Nitish

+1

是的,但是如果通知有效載荷包含非0值的「徽章」鍵,徽章應自動設置。 –

回答

1

無法使用公共API獲取此信息。

Local and Remote Notifications Programming Guide

讓我們回顧一下,當系統 提供了一個本地通知或應用程序的遠程通知可能出現的可能的情況。

通知在應用程序沒有在 前臺運行時傳遞。在這種情況下,系統會顯示通知, 顯示警報,標記圖標,可能播放聲音,並且可能會顯示一個或多個操作按鈕供用戶點按。

用戶點擊iOS 8通知中的自定義操作按鈕。在這種情況下,iOS調用 application:handleActionWithIdentifier:forRemoteNotification:completionHandler: 或 application:handleActionWithIdentifier:forLocalNotification:completionHandler :. 在這兩種方法中,您都可以獲得操作的標識符,以便您可以確定用戶點擊哪個按鈕。您還可以獲得遠程 或本地通知對象,以便您可以檢索任何需要處理該操作的信息 。

用戶點擊提醒中的默認按鈕或點擊(或點擊) 應用程序圖標。如果輕擊默認操作按鈕(在運行iOS的設備上),系統啓動應用程序,應用程序調用其應用程序:didFinishLaunchingWithOptions:方法,傳入 通知負載(用於遠程通知)或 local-通知對象(用於本地通知)。儘管 應用程序:didFinishLaunchingWithOptions:不是 處理通知的最佳位置,但在此時獲取有效負載將使您 有機會在調用處理程序方法 之前啓動更新過程。

對於遠程通知,系統還會調用 應用程序:didReceiveRemoteNotification:fetchCompletionHandler: 應用程序委託的方法。

如果在運行OS X的計算機上單擊應用程序圖標,應用程序會調用 代理的applicationDidFinishLaunching:代理可以獲取遠程通知有效負載的方法。如果在運行iOS的設備上輕按應用圖標 ,該應用將調用相同的方法,但 不會提供有關該通知的信息。

正如您所看到的,當應用程序從死亡狀態或未鎖定狀態開始時,只能檢查點擊通知。

另外重要的一點是:

服務質量

蘋果推送通知服務包括執行一個存儲和轉發功能服務 (QoS)的組件的默認質量。如果APN 嘗試傳遞通知但設備處於脫機狀態,則 通知將存儲一段有限的時間,並在設備可用時傳送至 。只有一個最近通知 的特定應用程序被存儲。如果在 設備處於脫機狀態時發送了多個通知,則新通知將導致先前的 通知被丟棄。只保留最新的 通知的行爲稱爲合併通知。

如果設備長時間保持脫機狀態,則會丟棄爲其存儲的任何通知 。

所以,長話短說,交貨&存在推通知是高度可預期的,但不能保證。此外,設備上的推送通知路徑不會以編程方式控制 - 作爲應用程序,您在設備上訂閱APNS守護程序,並且您依賴推送通知。

這就是爲什麼,如果你的應用程序有一些業務邏輯(在你的情況下,計數器更新),你不應該依賴推送通知。您應該使用更可靠/可控的機制來同步應用程序和後端之間的數據。我通過使用REST並在我的應用程序的問題域中專門使用Notification實體幾次實現了這一目標 - 用戶可以獲取通知,將它們標記爲已讀/未讀,並通過REST API刪除它們等。

+1

感謝您的解釋。說得通。似乎像Facebook這樣的應用程序使用私有API來實現此目的。我喜歡你創建單獨的實體來處理通知的方法。使功能更清晰。 – Nitish

+0

我相信,facebook和linkedin沒有使用私有API - AFAIK,它們爲每個選項卡(Messenger,通知,朋友請求,當它關於Facebook和LinkedIn幾乎相同)都有單獨的計數器。我認爲,他們使用REST或一些websocket機制來獲取更新和某種緩存。如果你在Facebook應用程序的啓動早期有徽章計數 - 它們從緩存中獲得99.99%,然後通過網絡連接從網絡更新 –

+0

你可以給出關於最後一句話的更多細節:「我已經實現了這個目標很少通過使用REST並在我的應用的問題域中專用通知實體 - 用戶可以獲取通知,將它們標記爲已讀/未讀,通過REST API刪除它們等「 – Honey

-1

如果用戶通過單擊通知或者如果應用程序處於打開狀態來打開應用程序,則只能獲取通知有效負載信息。在這兩種情況下,didReceiveRemoteNotification都會調用。除此之外,您可以在應用程序打開時調用服務器上包含通知計數信息的服務。

0

您可以將一些參數添加到json接收到推送通知中的數據中,例如"type":1以識別通知的類型。見Examples of JSON Payloads。但是來自API的通知的加載計數更好,然後將每種類型的通知計入應用程序。

1

所以基本上,總結別人的話,你會有兩個用戶案例。但是在你需要在你的有效載荷中指定哪個徽章必須增量之前(如@Andrew建議)。 下面是用戶案例:

  1. 應用程序可以調用didReceiveRemoteNotification。在這種情況下,這意味着該應用程序處於後臺或前臺,或者通過點擊通知啓動。你將不得不實施你的邏輯來處理這種情況。只是解析你的通知的有效載荷(在JSON中)並確定你應該增加哪個徽章。
  2. 該應用不能撥打didReceiveRemoteNotification。在這種情況下,用戶已經殺死了您的應用,或者該設備已關閉,或者該用戶已爲您的應用攔截獲取後臺功能。要處理這種情況,您的應用程序和服務器上還需要更多的邏輯。 你可以做的是在服務器端存儲所有發送的未決通知。一旦用戶設備上的應用程序收到解析通知(調用didReceiveRemoteNotification),您將向服務器發出一個新的呼叫,要求從待處​​理的數據庫中刪除通知。最後,在您的應用程序啓動時實施一個致電您的服務器的請求,以便在您的應用程序被終止或設備關閉的情況下,當用戶再次打開該應用程序時,他將收到所有通知錯過。您還可以在服務器上設置一個計時器,以每x天/每小時再次發送一次通知(這並不是真正的建議,您不希望用戶因爲垃圾郵件而刪除您的應用)。

也像其他人所說的那樣,信任你的服務器應該在你的徽章上顯示的數字比通知本身更好。上面的邏輯用於最近正在處理的類似Tinder的應用程序,以顯示用戶有多少匹配;)