關于推送(無法獲取DeviceToken)

? 近日公司來了新的后臺,說他原先集成的是百度推送。然而我們App老版用的都是極光推送。無奈我們換成了百度推送。但是測試推送的時候,百度推送網站的web后臺老是出現“網絡原因,無法發送推送”的提示,搞得連測試也沒法測,絕對不是我證書的問題。在這里我要吐槽一下百度推送,要么出現以上網絡原因,發不出推送。要么推送有延遲,一下收到好幾條。反正我對百度推送的感覺已經很不好了。最后又換回了極光推送。

? 原本十分鐘就能搞完的東西,結果出了莫名其妙的問題。


? 極光推送打印臺提示:[JPUSHClientController] Not get deviceToken yet。也就是代理中?

?- (void)application:didRegisterForRemoteNotificationsWithDeviceToken:和- (void)application didFailToRegisterForRemoteNotificationsWithError:不調用。

原先都是按照demo一步一步來的,如今出現了這個問題,那種感覺就像無數只草泥馬奔騰而過,這才讓我從頭到尾對推送原理擼了一遍,特此記錄下來,給大家分享。

? 證書就不多說了,唯一注意的一點是在你創建開發推送證書的時候類型應該是Apple Push Notification service SSL (Sandbox),不是app Development。這里有幾份詳細的集成過程和對推送在AppDelegate中的封裝,感覺不錯。

iOS集成極光推送,繞過一些坑

史上最全的推送教程

極光推送常見問題官方文檔

大部分的問題都可以在以上找到解決方案,我來列舉幾個比較容易遺漏的點;

? 1.推送設置setupWithOption中的appKey要和推送平臺上注冊時給的一致,isProduction 為NO就是開發狀態,為YES就是生產狀態。

? 2.程序設置中的Capabilities中 Remote notification要打對勾

? 3.確定你的手機聯網并打開通知權限

? 4.代碼中是否重寫了AppDelegate中的方法(百度時有人提到了環信API重寫了獲取Token的方法)

? 5.確定你的代碼中有這個

? 很多人問題都出在了第五種情況上。

? 然而我的經過徹底的排查,還是不調用獲取DeviceToken的函數,這種情況下,我拿同事的手機測試就能獲取到DeviceToken。但別高興的太早,如果你把APP卸載了重新打包就獲取不到了,原因是第一次打包調用registerForRemoteNotificationTypes注冊成功后,之后即使不聯網,再調用都會以最上一次的device token作為參數回調didRegisterForRemoteNotificationsWithDeviceToken方法,除非你卸載了重裝,這時的APNs要向你發送新的DeviceToken,這時就獲取不到了,這就是我現在的問題,然后就會報[JPUSHClientController] Not get deviceToken yet。這個問題折磨了我一天,舊版的推送SDK也換過,依舊不行。碉堡的是第二天早上再打包的時候莫名其妙的就好了,簡直嗶了狗。我沒有作任何改動。按照我的理解,應該是證書從蘋果開發者中心分發下來驗證要經過一段時間,或是Xcode Bug,或者是用這個證書在與百度推送綁定后再與極光綁定時發生了微妙的變化,反正問題就這樣解決了。


? 下面是收到推送時的一些知識點和坑,大家可以交流一下

1.注意:App在活躍狀態時是收不到推送通知的橫幅的

2.App在后臺狀態時,點擊推送會調用-(void)application:didReceiveRemoteNotification:fetchCompletionHandler:在這個函數里判斷applicationState從而做相應的處理。

注意,這里有個坑.從后臺點擊推送進入前臺,進入到這個函數里時,application的狀態是InActive,而非Active或Background。開始我還以為這個狀態是殺死狀態,其實應該叫空閑狀態。那么這個函數里只需要判斷UIApplicationStateActive(正在使用)和UIApplicationStateInActive(從后臺進入前臺)狀態。


幫助大家理解一下這倆狀態的區別


3.當App在殺死狀態下點擊推送(注意不是點擊APP)并不會執行以上函數,而會進入到- (BOOL)application: didFinishLaunchingWithOptions:,不點擊推送時launchOptions為nil,這時推送的內容都在launchOptions里,可以用以下方法獲取

上面這個方法里,我把角標設為0,并且把數據以通知的方式傳遞給self.window.rootViewController。這里我用了一下延時操作,因為立即傳的話,rootViewController還沒有初始化完成,是收不到這個通知的。不知道各位大神還有沒有更合理的解決方法,歡迎提出。

以上就是我推送的艱辛歷程,僅代表個人對推送的理解,歡迎各位大神指出錯誤,謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容