問題背景:
項目中發(fā)現(xiàn)有一臺手機(jī)收不到推送消息甚疟,后臺信息顯示RegistrationID為空。
相關(guān)知識點(diǎn):
RegistrationID 的定義
關(guān)于 RegistrationID 極光官方文檔有如下的定義:
集成了 JPush SDK 的應(yīng)用程序在第一次 App 啟動后送漠,成功注冊到 JPush 服務(wù)器時盲再,JPush 服務(wù)器會給客戶端返回唯一的該設(shè)備的標(biāo)識 – RegistrationID甜无。JPush SDK 會以廣播的形式發(fā)送 RegistrationID 到應(yīng)用程序撒璧。
有了這個標(biāo)識群扶,App 編程可以把這個 RegistrationID 保存到自己的應(yīng)用服務(wù)器上及刻,然后就可以根據(jù) RegistrationID 來向設(shè)備推送消息或者通知。
RegistrationID 變化可能性
1.如果 App 不卸載竞阐,是直接覆蓋安裝缴饭, iOS 上 RegistrationID 的值都不會變化。
2.如果 App 是卸載之后再次安裝:iOS 上如果啟用了 IDFA 變化可能性不大骆莹,如果未啟用 IDFA 則每次安裝 RegistrationID 都會變颗搂;
RegistrationID 生成規(guī)則解析
鑒于 iOS 系統(tǒng)設(shè)計上限制設(shè)備唯一標(biāo)識,所以極光一直使用 Device Token 作為標(biāo)識幕垦,也因?yàn)闃O光推送本身就是需要 Device Token 這個值才可能運(yùn)作的丢氢。
iOS 9 版本之后,每次卸載后重裝都會導(dǎo)致 Device Token 變化先改,所以對于極光后臺來說疚察,都只能被識別為新用戶。
極光 SDK 新版本增加了 IDFA 選項仇奶,在集成初始化 SDK 時可選把 IDFA 這個值設(shè)置進(jìn)來貌嫡,這樣極光后臺就優(yōu)先根據(jù) IDFA 值來識別用戶,從有一定的可能性應(yīng)用被卸載后重裝還能識別回老設(shè)備。
IDFA 是廣告標(biāo)識符衅枫,是 iOS 專門為廣告跟蹤唯一地識別用戶而設(shè)計的嫁艇。在 iOS 設(shè)備上,設(shè)備 -> 隱私 -> 廣告這個頁面弦撩,有一個設(shè)置項:限制廣告跟蹤步咪。默認(rèn)是未選中狀態(tài)的,即是關(guān)閉狀態(tài)益楼,是不限制的猾漫。用戶可以選中,從而限制廣告跟蹤感凤。設(shè)置項之外還有一個按鈕:還原廣告標(biāo)識符…悯周。如果用戶點(diǎn)擊了這個按鈕,則 IDFA 值會變化陪竿。
默認(rèn)的情況下禽翼,沒有限制廣告跟蹤,可以取到 IDFA 這個值族跛。并且用戶未點(diǎn)擊『還原廣告標(biāo)識』時闰挡,這個值是不會變的。這樣就達(dá)到了唯一地標(biāo)識設(shè)備礁哄、跟蹤到用戶的目標(biāo)长酗。
總之: Device Token + IDFA = RegistrationID;
解決方案:
因?yàn)镽egistrationID 是在JPush服務(wù)器注冊后才得到的桐绒,所以在調(diào)用SDK獲取 RegistrationID時夺脾,并不能馬上得到該值≤约蹋可以在ios上監(jiān)聽kJPFNetworkDidLoginNotification
通知的代碼里獲取該值咧叭。
代碼如下
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
//進(jìn)行推送消息的注冊
[APServiceregisterForRemoteNotificationTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[APServicesetupWithOption:launchOptions];
NSNotificationCenter*defaultCenter =[NSNotificationCenterdefaultCenter];
[defaultCenteraddObserver:self
selector:@selector(networkDidLogin:)
name:kJPFNetworkDidLoginNotification
object:nil];
returnYES;
}
- (void)networkDidLogin:(NSNotification*)notification {
NSLog(@"已登錄");
NSString *registrationIDStr = [APService registrationID];
if(![CommonUtility isBlankString:registrationIDStr]){
[UserInfo saveRegisterId:registrationIDStr];
}
}