1. 程式人生 > >APNS推送以及app內部訊息處理、本地通知的使用

APNS推送以及app內部訊息處理、本地通知的使用

        APNS具體的流程大概就是:app註冊APNS推送功能,app就會通過iOS系統向APNS伺服器要devicetoken,然後將devicetoken傳給app的推送伺服器,推送伺服器帶著P12檔案和device token,以及要推送的訊息,傳送給蘋果伺服器。隨後就是上述步驟啦。需要注意的是:xcode必須配置Profile,才能接受訊息。而推送服務端則必須要,攜帶推送證書的P12檔案,與APNS推送伺服器傳輸訊息。

    關於device token,還要多少兩句,在開發和生產環境中的同一個iPhone和app對應的device token是不一樣的,而且它也會改變。如果改變了,我們怎麼辦。這個人說的很好,這裡轉載一下。

正是因為device有可能改變,所以建議在app start時(即在didFinishLaunchingWithOptions  裡)呼叫registerForRemoteNotificationTypes來獲取device token以檢查device token是否改變,如果改變了就應該把新token傳給push provider。(官方描述:An application should register every time it launches and give its provider the current token)device token應該儲存在NSUserDefaults來達到新舊比較的目的

那麼舊device token在push provider對應的record怎麼辦?

方案1:把舊device token send to provider and request delete record

方案2:使用apns feedback service。

方案2可能更好些,因為總是需要使用apns feedback service來處理使用者在device裡刪除app的情況。

呼叫registerForRemoteNotificationTypes方法後,成功註冊後,APNS就會返回一個device token,然後回撥delegate methoddidRegisterForRemoteNotificationsWithDeviceToken

, 如果註冊失敗,則回撥delegate method didFailToRegisterForRemoteNotificationsWithError。

注意:

* 在第一次呼叫registerForRemoteNotificationTypes方法沒有聯網,則既不會呼叫didRegisterForRemoteNotificationsWithDeviceToken,也不會呼叫didFailToRegisterForRemoteNotificationsWithError

*第一次呼叫registerForRemoteNotificationTypes註冊成功後,之後即使沒有聯網,再呼叫registerForRemoteNotificationTypes時都會以最上一次的device token作為引數回撥didRegisterForRemoteNotificationsWithDeviceToken方法。

(官方描述) If your application has previously registered, calling registerForRemoteNotificationTypes: results in the operating system passing the device token to the delegate immediately without incurring additional overhead.

    看完這位說的,那麼我的問題來了:什麼是apns feedback service。然後就看到下面這位說的重要規則。記錄下來。

前段時間,仔細研究了APNS的文件,把一些關鍵的地方記錄了下來,弄懂這些對於理解APNS的規則,至關重要。

1. If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available.

假如使用者手機不線上,可能沒有訊號或者關機吧,APNs會儲存轉發,等使用者線上時再發送

2.Only one recent notification for a particular application is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification is referred to as coalescing notifications.

如果使用者不線上,通知會合並,只會保留最新的一條。假如你給使用者發了兩條通知,但使用者反饋說,只收到了一條,那麼很可能是使用者當時不線上,APNs的合併策略生效,只保留了最近一條

3.If the device remains offline for a long time, any notifications that were being stored for it are discarded

4.The maximum size allowed for a notification payload is 256 bytes; Apple Push Notification Service refuses any notification that exceeds this limit.

這個很重要,payload,就是最後生成的那段Json,不得超過256位元組。如果超過了,建議去掉一些不需要的引數,把alert,就是提示資訊的字數減少

5.don’t repeatedly open and close connections. APNs treats rapid connection and disconnection as a denial-of-service attack.

6.If you send a notification that is accepted by APNs, nothing is returned.

傳送成功的木有返回,只有傳送失敗的才會返回

7.If you send a notification that is malformed or otherwise unintelligible, APNs returns an error-response packet and closes the connection. Any notifications that you sent after the malformed notification using the same connection are discarded, and must be resent.

這條非常重要,如果有error-response,那麼這條之後的通知都需要重發。有很多開源的庫,在發蘋果通知時都沒有檢測error-response,如果你不小心用了,那麼使用者很可能反饋“怎麼沒有通知啊”

8.The notification identifier in the error response indicates the last notification that was successfully sent(實際情況不是,實際上返回的是出錯的那條通知的ID). Any notifications you sent after it have been discarded and must be resent.When you receive this status code, stop using this connection and open a new connection.

這是對上一條的補充,如果出錯了,需要關閉當前的連線,並且重新連線再發。error-response中返回的通知ID,可以幫助我們找出哪條出錯了,這樣就能知道哪些需要重發了

9.When a push notification cannot be delivered because the intended app does not exist on the device, the feedback service adds that device’s token to its list.

APNS的feedback service會返回那些已經解除安裝的裝置的token--device_token。儲存這些token,下次就不用再給他們發了,可以節省點資源。需要注意的是:feedback的介面讀取一次,APNS就會清空它的列表,下次再讀取時,返回的就是這兩次讀取之間這段時間新產生的device_token。

    接下來是另外一位的更新版

蘋果APNs’ device token特性和過期更新

APNs全名是Apple Push Notification Service。用iPhone的應該都習慣了,每次安裝完一個新應用啟動後,幾乎都會彈出個警告框,“XXX應用”想要給您傳送推送通知。這個警告框的許可權申請就是為了APNs推送,使用者授權後,應用提供商就可以通過APNs給使用者推送訊息。
APNs的工作機制簡單來說可以分為兩步,第一步是註冊推送服務從APNs獲取device token來告知應用提供商服務端,第二步是應用提供商服務端通過APNs給裝置推送訊息,device token是作為裝置的唯一標示。
token_generation_2x
上圖就是device token生成的一個過程。我們以第一次安裝啟動360兒童衛士應用為例,首先應用會彈出個警告框,請求使用者允許傳送推送通知,使用者允許後–>兒童衛士會向系統註冊推送服務,系統接到註冊請求後就會自動連線APNs伺服器請求獲取裝置令牌(即device token)–>APNs伺服器生成包含device id的device token並下發給裝置–>兒童衛士接受到device token,儲存在本地同時傳送給兒童衛士伺服器,到此第一步就完成了。
token_trust_2x
上圖就是推送訊息的示圖了,裝置通過device token和APNs伺服器保持連線狀態。還以360兒童衛士為例,當孩子到家了,兒童衛士伺服器就需要發到達提醒給家長。這時兒童衛士伺服器就會通過device token作為目的裝置標示來推送加密的到達提醒訊息給APNs,APNs解密後再根據device token推送給指定裝置。這樣,一次推送就完成了。
瞭解了APNs工作機制,很明顯能夠看到device token在其中起了至關重要的串聯指向作用。如果device token錯誤或缺失,推送就無法送達目標裝置了。所以測試也罷開發也好,都很有必要了解一下device token的一些特性:
1.每個device token都是唯一的,只會對應一臺裝置。
2.device token與裝置系統相關(注意不是和裝置繫結的!詳解見後文),同一裝置系統上不同應用獲取的token是同一個。
3.應用解除安裝重新安裝,獲取到的device token不會變化,而且不會再彈出推送許可權申請的彈窗,會自動繼承前一次安裝的設定資訊。這個特性容易引發一些安全問題,使用者解除安裝重新安裝一個應用後,還沒有登入應用,就可能接到上次登入帳號的推送訊息了。我使用iPhone QQ和Skype都碰到過這種情況。客戶端沒有辦法處理這個問題,因為被解除安裝時客戶端是沒法做出反應來通知伺服器的。蘋果有一個feedback的機制可以解決這個問題,蘋果為每個應用程式維護了一個不斷更新的推送失敗的裝置列表。服務端可以去定期檢查並更新推送裝置列表,這樣能解決大部分問題,也能減少不必要的報文開銷。
4.第三點客戶端不能處理,但退出登入通知伺服器就是客戶端的工作了。使用者退出登入客戶端時,客戶端應該告知伺服器,停止對這個裝置繼續推送使用者退出登入帳號的訊息了。這點應該不算device token的特性了,是一個標準處理方法。
相信很多人都有這樣一個疑問,作為一個裝置推送的唯一標示,device token是否會變化或者過期呢?蘋果在這點上有些含糊其辭,只是在官方文件上建議開發者在每次啟動應用時應該都向APNs獲取device token並上傳給伺服器。從這句話來看,device token是會變化的,不然不用每次啟動都去獲取。因為蘋果官方沒有給出明確的device token變化的情況,所以以下列舉的都是一些前人總結的經驗,主要援引了stackoverflow上關於這個問題一個回答,回答者稱是和蘋果的一個工程師交流及自己實驗得出的結果。
1.升級系統device token有可能變化,確認的是升級到iOS5會變化,猜測是升級大的系統版本後device token會變化。
2.抹掉所有內容和設定,reset裝置後,device token會變化。
3.恢復一個非本機的備份後,device token會變化。
4.device token會過期,這個眾說紛紜,有說是半年的,有說一年,有說兩年的,不過會過期應該是確鑿的。
5.備份或者恢復本機的備份,device token不會變化。
所以保險起見,按照蘋果的每次啟動應用時檢查device token併發送到伺服器是比較穩妥的做法。

       接下來是一位php coder的一些注意點

注意事項:

1.建議和feedback伺服器建立長連線,連線過於頻繁有可能被當做攻擊(簡簡單單的做一些測試時沒有關係的);

2.獲取的token是在上次你給你的應用發推送失敗時加feedback服務的,裡面會返回失敗的具體時間

3.返回的資料由三部分組成,請看下面的圖

1357647920_4440結構中包含三個部分,第一部分是一個上次發推送失敗的時間戳,第二個部分是device_token的長度,第三部分就是失效的device_token

     現在開始處理推送的訊息。首先來說一下這些方法:

 1.func applicationWillResignActive(application: UIApplication){} 當App既將進入後臺、鎖屏、有電話進來時會觸發此事件

   2.func applicationDidEnterBackground(application: UIApplication) {} 當App進入後臺時觸發此事件

   3.func applicationWillEnterForeground(application: UIApplication) {} 當App從後臺即將回到前臺時觸發此事件

   4.func applicationDidBecomeActive(application: UIApplication) {}當App變成活動狀態時觸發此事件

   5.func applicationWillTerminate(application: UIApplication) {} 當App退出時觸發此方法,一般用於儲存某些特定的資料

- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken 

 - (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error

為了讓device端可以接收到推送訊息,需要將裝置的token傳送到蘋果的伺服器,這個token就相當於裝置的識別碼,每一臺蘋果裝置都有唯一的token,蘋果的伺服器就是通過這個token找到對應的裝置,並傳送相應地訊息。這兩個函式就是在傳送token成功或者失敗後呼叫的,使用者在對應的函式裡面做一些相應地處理。 一般都是在成功接受到token的地方處理,將token傳給自己應用的推送伺服器。
如果app處於前臺或者後天的時候,收到推送的時候,進入方法:

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

都是程式在執行過程中(無論當前程式處於前臺還是後臺)接收到推送訊息的處理函式。根據蘋果的官方文件,建議大家使用

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

因為前者在程式處於後臺的時候是無法接收到推送資訊的(經實測-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo其實可以接收到,不知道是怎麼回事,希望大蝦解疑)。另外就是-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 還有一個作用。根據蘋果給出的文件,系統給出30s的時間對推送的訊息進行處理,此後就會執行CompletionHandler程式塊。

在處理這類推送訊息(即程式被啟動後接收到推送訊息)的時候,通常會遇到這樣的問題,就是當前的推送訊息是當前程式正在前臺執行時接收到的還是說是程式在後臺執行,使用者點選系統訊息通知欄對應項進入程式時而接收到的?這個其實很簡單,用下面的程式碼就可以解決:

?
1 2 3 4 5 6 7 8 9 10 11 12 voidapplication:(UIApplication*)application didReceiveRemoteNotification:NSDictionary)userInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{ if(application.applicationState == UIApplicationStateActive) { NSLog(@"active"); //程式當前正處於前臺 } elseif(application.applicationState == UIApplicationStateInactive) { NSLog(@"inactive"); //程式處於後臺 } }
關於userInfo的結構,參照蘋果的官方結構:
?

相關推薦

APNS以及app內部訊息處理本地通知的使用

        APNS具體的流程大概就是:app註冊APNS推送功能,app就會通過iOS系統向APNS伺服器要devicetoken,然後將devicetoken傳給app的推送伺服器,推送伺服器帶著P12檔案和device token,以及要推送的訊息,傳送給蘋果伺

微信公眾號開發訊息以及圖文

今天給大家分享的關注公眾號自動推送圖文訊息,以及做一個超牛逼的機器人。 先看看效果。 發錯圖了。。。這是我昨天開發的一款機器人chu了會罵人啥都不會了。 我今天將它詞庫進行了更新和升級,接入了http://www.itpk.cn/ 機器人第三詞庫 先給你截圖

APNS訊息

解釋: 1.Your App在AppDelegate代理中,註冊APNS訊息推送功能; 2.當蘋果APNS推送服收到來自你應用的註冊訊息就會返回一串device token給你(很重要); 3.將應

APP訊息APP Push)解決方案-服務端工作邏輯和實現

一、APP 推送概述: App推送訊息是我們常見的一種app訊息提醒方式。 我們的實現需要第三方的支援,實現方式是後臺通過介面將Push請求傳送至第三方,第三方實現在App所在裝置上的推送。 二、APP推送後臺處理邏輯: 在與推送平臺互動時,後臺需要向第三方傳送兩部分資訊

[git] github 以及沖突的解決

代碼 update 指向 origin 所有 test 新版本 .com 服務 推送以及沖突的解決:   1、查看分支狀態(查看所有:當前檢出分支的前面會有星號) git branch   2、切換分支 git checkout test(分支名)#創建並切換分支gi

Java後臺向蘋果APNS文字,圖片,視訊功能

務虛廢話,直接來程式碼 方式一: 推送文字,百度Demo比較多,顯示以下程式碼:   try { //從客戶端獲取的deviceToken,在此為了測試簡單,寫固定的一個測試裝置標識。 String device

騰訊移動(穩定可靠的訊息通道 雙Service聯合保活)

高抵達率,穩定長連線 業內領先的技術實力,穩定可靠的訊息推送通道 雙Service聯合保活,與騰訊系應用共享通道 有效提升訊息抵達率 ----https://xg.qq.com/ctr_index/intro   SraumSmartHome com.massky.sr

webSocket-簡單的服務端定時以及重連

本文章是對webSocket的學習,在使用webSocket進行客戶端-服務端的互動。 參考文章: Java基於Socket的簡單推送,在文章在服務端 輸入後回車 ,可進行對客戶端的資訊傳送,同時進行回饋。 以下為自行改進:服務端定時推送資訊到客戶端,可根據自行需要進行調整。

iOS 極光接收自定義訊息

//新增監聽者     NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];     [defaultCenter

第一篇部落格:極光以及自定義聲音

極光註冊就不說了,首先配置App的build.grandle 在defaultConfig裡貼上一下內容appkey為我在極光註冊之後的Appkey 然後配置AndroidManifest  把下面這些資訊放在application裡面 <!--極光的-->

java微信模板訊息

/** * 註冊成功,通知模板訊息實體類 */ public class TemplateMessage { private String touser; //使用者OpenID private String template_id; //模

Android雲巴整合第三方實現APP偽保活(小米篇)

此文只是講述如何使用雲巴自帶的包實現該功能,核心技術並不是博主寫的。此功能實現首先實現基礎的推送,沒有實現的請看SDK快速入門,實現了的可以直接去官方文件怎麼整合第三方,雲巴文件傳送門,那我為什麼要寫這篇博文,我是不會和你講的,進入正題: 1.新建專案

主流的幾種以及比較

百度雲推送點評:百度雲推送可謂為使用者體驗而生,它實現了多項創新,並通過百度各大產品線千萬級連 接的可用性測試,迅速成為國內第三方雲推送平臺的標杆。據瞭解,在百度雲推送正式釋出之前,大部分的百度產品其實都已在使用百度雲推送,例如百度框、百度 網盤、百度地圖、百度視訊,已覆蓋

PHP快速微信模板訊息

需要給關注使用者傳送模板訊息,由於公眾號關注使用者比較多,所以採用普通的curl等方式太慢。由於模板訊息傳送不需要等待微信的結果,所以利用php的fsockopen()函式可以達到快速傳送的效果。程式碼

iOS 本地以及自定義聲音

iOS10.0以後蘋果要求本地推送使用UserNotification框架來做本地推送, 下文就該框架下做推送以及自定義推送聲音做下介紹 1.AppDelegate.m: 1.匯入框架並遵循協議: #import <UserNotificat

SignalR+HTML5實現訊息及Android通知欄訊息

最近在研究使用SignalR實現跨平臺的訊息中心,WebAPI+SignalR作為資料介面和訊息中心,客戶端包含WPF桌面應用、Web應用和Android移動應用。這其中關鍵的功能點在於接收到實時訊息後的通知提醒,桌面應用和Web應用實現相對簡單,Android

本地.極光.APNs

1.本地推送的簡單應用 2.APNs介紹 3.使用極光推送向你的APP推送一條資訊 一.本地推送 本地通知推送也叫鬧鐘通知, 這是通知中比較簡單的一部分. 如果將app比喻成一個人, 某個controller比喻成身體的某一部分(手臂), 那麼由手臂註冊通知並且傳送通知

python3 三行程式碼基於HTTP2完美實現APNS【詳解】

    第一次做蘋果APNS(Apple Push Notification service)推送,關於APNS推送原理以及證書的獲取方式網上已經有許多資料,在此不做過多贅述,需要注意的是證書分為測試證書和正式證書兩種,建議直接用通用版的正式證書 大家可以參考網上的這篇部落格:點選這裡檢視

極光能獲取 registrationId,但是接收不到通知 - iOS

整合極光推送進行除錯的時候,執行 App 可以正常獲取 registrationId,但是卻遲遲無法收到推送訊息,而Android 端是可以正常收到訊息; 檢查了證書配置和極光的配置一切正常,便開始返回檢視 code 尋找問題. 最終發現如下方法中的 deviceToken 被注掉後導致註冊 i

MFC中CWnd類及其派生類對話方塊訊息處理視窗操作

CWnd類 我們在螢幕上看到的所有物件都和視窗有關,它們或者派生於CWnd,屬繼承關係,如對話方塊、工具欄、狀態列、子控制元件;或者被CWnd合成,屬服務員與服務物件關係,如圖示、選單、顯示裝置。 CWnd類封裝的視窗操作主要包含視窗的建立和銷燬、操作視窗風格、操作視窗狀態