MUI使用個推推送流程分析

mobile墨白發表於2018-10-11

需求:app通知欄收到推送,點選通知欄推送可以進入到不同的詳情頁(使用個推後臺除錯資料)

1、監聽方法分析:

  • receive方法:
    當APP在前臺的時候,可以監聽接收透傳訊息,APP不在前臺的時候無法監聽
 plus.push.addEventListener("receive", function (msg) {
 }
複製程式碼
  • click方法:
    1、iOS APP處於後臺,透傳訊息會變成通知提醒,此時點選通知觸發
    2、點選本地設定的推送到通知欄的通知
plus.push.addEventListener("click", function (msg) {
}
複製程式碼

2、技術分析:

通知欄通知:

  • iOS
    在個推中,iOS 只有透傳,沒有通知。當APP不在前臺時,透傳只在通知欄提醒,點選走click方法處理業務;
  • Android
    APP透傳訊息都不會出現在通知欄,有兩種處理方式:
    1、個推傳送通知(但是點選通知只能開啟APP、開啟連結、下載應用)
    2、收到透傳訊息後,本地生成通知到通知欄(僅限於APP處於前臺,receive方法中處理)

透傳訊息:

  • APP處於前臺才可接收到,APP處於後臺無法接收。且接收透傳訊息時,不可以直接做跳轉頁面等業務處理,業務處理跳轉等需在點選通知欄後進行相應處理。

3、工欲善其事必先利其器,先看官方常見問題:

MUI使用個推推送流程分析
image.png

4、邏輯處理:

iOS

  • APP處於前臺:

伺服器端推送透傳訊息後,直接在receive方法監聽到:


MUI使用個推推送流程分析
iOS APP處於前臺.png

但是這不是我們要的。我們需要的是使用者收到訊息後在通知欄出現,而不是直接在receive方法中做業務處理。那麼我們可以看下上面官方常見問題第三點,我們需要在訊息中心建立一個本地訊息:

plus.push.createMessage( str, "LocalMSG", options );
複製程式碼

通過點選通知中心的這個本地訊息,進入app實現click方法監聽處理業務。
那麼問題來了,經過測試我們發現,在建立本地訊息的時候(receive方法中),APP一定是處於前臺的,那麼建立了本地通知以後,我們的receive方法一定會監聽到,這樣不就進入到一個死迴圈了麼?

receive監聽 -> 建立本地通知 -> receive再監聽到本地通知 -> 再建立本地通知。。。

子子孫孫無窮盡也。

那麼我們可以根據參考常見問題的第三點:使用者在建立IOS本地訊息是可以在“payload”節點新增特殊標記對訊息進行區分。
這玩意是在建立訊息的時候,官方模板自帶的一個引數。在個推後臺iOS透傳的時候,有一個:

MUI使用個推推送流程分析
image.png


這個其實只是就是把payload引數的值變成你的透傳訊息json,那麼本地建立通知的時候這個值是什麼呢?我們看上面建立本地通知的時候,第二個引數LocalMSG,這個就是我們自定義在本地推送的時候的payload引數的值。所以,在receive方法中,我們根據payload引數的值是不是我們設定的LocalMSG就可以判斷監聽到的推送是不是本地建立的了。

  • APP處於後臺:

當APP處於後臺,receive方法監聽不到訊息,此時訊息走訊息中心推送,點選後進入APP內,走click方法處理業務,滿足需求。


MUI使用個推推送流程分析
iOS APP處於後臺.png

Android

根據常見問題第二點,我們知道在處理Android訊息的時候,需要使用標準格式的透傳json:

{title:"通知標題",content:"通知內容",payload:"通知去幹嘛這裡可以自定義"}
複製程式碼

這樣,透傳訊息就不會走receive方法,而是像我們需求那樣實現所有通知進入通知中心,點選通知中心走click方法處理。如果不按照此格式來,訊息不會走訊息中心,而是直接走監聽的receive方法(APP在前臺時,不在前臺時,透傳訊息甚至監聽不到)。

MUI使用個推推送流程分析
Android APP訊息流程梳理.png
需要注意的一點是:

Android透傳格式{"title":"通知1","content":"通知內容","payload":"{"type":"notify","payload":"通知去幹嘛這裡可以自定義"}"}如果想要傳輸自定義json,賦值給payload,但是裡面的json必須是轉義過後的,且任何和官方規定格式在同一層的欄位都是無效的,例如:
{"id":"123","title":"通知1","content":"通知內容","payload":"{type:\"notify\",ids:\"456\"}"}
這裡面第一個id:"123"在實際接收到的時候並不會存在。

5、總結

其實扯了一大堆,簡而言之就是一句話:

Android推送的時候要注意後臺返回的json滿足官方格式即可,iOS推送要注意當APP在前臺的時候,在receive方法監聽的時候判斷是否是本地通知。

下面是我的部分關鍵程式碼,alart()是測試階段為了看到效果加的:

        //獲取推送通知
        plus.push.addEventListener("receive", function (msg) {
            alert("接收到的透傳推送 " + JSON.stringify(msg));
            if (plus.os.name == "iOS") {
                switch (msg.payload) {
                    case "LocalMSG":
                        alert("本地建立訊息的 " + JSON.stringify(msg));
                        break;
                    default:
                        //測試本地推送
                        createLocalPushMsg(msg);
                        break;
                }
            }
        }, false);
複製程式碼
        //點選推送進來
        plus.push.addEventListener("click", function (msg) {
            // 判斷是從本地建立還是離線推送的訊息
            alert("點選處理訊息 " + JSON.stringify(msg));
        }, false);
複製程式碼
        //建立本地訊息
        function createLocalPushMsg(msg) {
            var options = {cover: false};
            plus.push.createMessage(msg.content, "LocalMSG", options);
            if (plus.os.name == "iOS") {
                outLine('*如果無法建立訊息,請到"設定"->"通知"中配置應用在通知中心顯示!');
            }
        }
複製程式碼
本文參考的官方文件附上


相關文章