今天遇到個客戶端沒有收到服務(wù)器APNS推送的問題,聯(lián)調(diào)了一下發(fā)現(xiàn)毒涧,是服務(wù)端與客戶端的device token不一致造成的,
而不一致的原因是客戶端沒有及時把device token發(fā)送到服務(wù)器贝室,
客戶端是在- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken NS_AVAILABLE_IOS(3_0);
方法中將device token發(fā)送到服務(wù)器的契讲,
所以問題是app又是什么時候才調(diào)用這個方法呢?
打斷點試了試發(fā)現(xiàn):
在調(diào)用UIApplication.shared.registerForRemoteNotifications()
方法后滑频,系統(tǒng)才會調(diào)用
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken NS_AVAILABLE_IOS(3_0);
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error NS_AVAILABLE_IOS(3_0);
其中一個
也就是說捡偏,如果沒有主動調(diào)用UIApplication.shared.registerForRemoteNotifications()
方法,那客戶端就不會再次吧device token發(fā)送到服務(wù)器了误趴。
理論上這個device token不會輕易變霹琼,但也不是不會變
(https://stackoverflow.com/questions/40169404/does-a-ios-push-notification-device-token-change有提到,當用戶擦除數(shù)據(jù)或者系統(tǒng)升級時凉当,就會變枣申,我自己的感覺是,隔一段時間就會變看杭。忠藤。。)
所以蘋果的建議是楼雹,每次啟動app都向apns服務(wù)器獲取device token 并發(fā)送到自己的服務(wù)器模孩。
但考慮到如果用戶剛安裝app的時候就彈出推送通知的提醒,90%會被拒掉贮缅,所以我們產(chǎn)品的設(shè)計是榨咐,當用戶需要推送時,再提示用戶開啟推送谴供,比如用戶訂閱某個訂閱號時块茁,告訴用戶可以開啟推送來第一時間知道該訂閱號有更新。
所以這里就需要一個判斷,app啟動時数焊,如果用戶還沒有開啟過通知永淌,就不要調(diào)用UIApplication.shared.registerForRemoteNotifications()
注冊通知,如果用戶已經(jīng)開啟了通知佩耳,那每次啟動都要調(diào)用這個方法更新device token遂蛀;
注意:如果app還沒有注冊過通知,即app的通知狀態(tài)是notDetermined
干厚,那系統(tǒng)設(shè)置的app設(shè)置里面都不會有通知設(shè)置的選項李滴,這時候調(diào)用UIApplication.shared.registerForRemoteNotifications()
會彈出系統(tǒng)的“XXX想要給您發(fā)送通知”那個alert出來,如果是已經(jīng)注冊過了萍诱,不管狀態(tài)是denied
還是authorized
悬嗓,都不會在彈那個alert出來了,但是還是會觸發(fā)系統(tǒng)的didRegisterForRemoteNotificationsWithDeviceToken
或者didFailToRegisterForRemoteNotificationsWithError
方法