2016-12-05 61 views
0

我正在使用Azure推送通知,並且注意到每次啓動應用程序時,APNS都會向我發送新的設備令牌。根據Apple的文檔,設備令牌通常應該保持不變:iOS應用程序每次都收到新的APNS設備令牌

包含在每個請求中的設備令牌代表接收通知的設備的標識 。 APN使用設備令牌 標識每個獨特的應用和設備組合。它還使用它們對 進行身份驗證,以發送到設備的遠程通知的路由。 每次您的應用在設備上運行時,它都會從APNs 中獲取該令牌並將其轉發給您的提供商。您的提供商存儲令牌, 在向該特定應用和設備發送通知時使用該令牌。 令牌本身是不透明且持久的,只有當設備的數據和設置被擦除時纔會改變。只有APN可以解碼並讀取設備令牌。

但是,根據通過Azure發送的失敗消息數量不變,我可以推斷出我的應用每次啓動應用時都會從APNS接收新的設備令牌。有人可以告訴我:

  1. 爲什麼我每次都得到新的設備令牌,即使我沒有更改手機設置或刪除應用程序?

  2. 在上面的Apple的摘錄中,它們是什麼意思「刪除設備的數據」? APNS使用哪些數據來確定「獨特的應用程序和設備組合」?

下面的代碼:

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 

    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { 
     UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | 
                          UIUserNotificationTypeAlert | 
                          UIUserNotificationTypeSound) 
                       categories:nil]; 
     [application registerUserNotificationSettings:settings]; 
    } else { 
     [application registerForRemoteNotifications]; 
    } 
} 


- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings 
{ 
    //initiate registration process with Apple Push Notification service 
    [application registerForRemoteNotifications]; 
} 

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) token { 

    // Setting token with Azure hub 
    [[MyAzureNotificationHub sharedInfo] setDeviceTokenData:token]; 
} 

回答

0

簡短的回答是,每次應用程序向APNS註冊時,設備標記都不應更改。 Apple

包含在每個請求中的設備令牌表示接收通知的設備的標識 。APN使用設備令牌 標識每個獨特的應用和設備組合。它還使用它們對 進行身份驗證,以發送到設備的遠程通知的路由。 每次您的應用在設備上運行時,它都會從APNs 中獲取該令牌並將其轉發給您的提供商。您的提供商存儲令牌, 在向該特定應用和設備發送通知時使用該令牌。 令牌本身是不透明且持久的,只有當設備的數據和設置被擦除時纔會改變。只有的APN可以解碼和讀取 設備令牌

我的應用程序每次都得到一個新的設備令牌,因爲我不是從數據轉換的deviceToken的數據類型爲字符串正確。 APNS發送設備令牌類型的數據,但在它傳遞到Azure的,我需要先令牌轉換爲字符串具有以下功能:

private func convertDataToString(data:NSData) -> String { 
     let singleChar = UnsafePointer<CChar>(data.bytes) 
     var tokenbuilder = String() 

     if data.length > 0 
     { 
      for index in 0...data.length - 1 
      { 
       tokenbuilder += String(format: "%02.2hhx", arguments: [singleChar[index]]) 
      } 
      return tokenbuilder 
     } 
     else 
     { 
      return "" 
     } 
    } 

就我而言,我已經忘記了的位置第一個字符從0開始(不是1),因此原始for循環從0變爲data.length(而不是data.length - 1),導致該函數返回一個帶有隨機多餘字符的字符串。即使使用具有額外字符的字符串,應用程序也確實收到了推送通知;但是,我們在Azure日誌中也有大量無效令牌。這也導致用戶每次啓動應用程序時接收新的deviceToken(並註冊設備令牌)。一旦我修復了for循環,只要應用程序未被刪除(因此刪除設備數據)並重新安裝到我的設備上,APNS就開始向用戶返回相同的設備令牌;從而創建一個「獨特的應用程序和設備組合」。

1

您可以參閱:

決不高速緩存設備令牌;當你需要它們時,總是讓它們從系統中獲得。儘管設備令牌對於應用和設備是唯一的,但它們可以隨時間變化。設備令牌可隨時更改,但在用戶從備份中恢復設備時,用戶在新設備上安裝應用程序以及用戶重新安裝操作系統時,設備令牌可能會有所不同。從系統中獲取令牌可確保始終擁有與APN進行通信所需的當前令牌。另外,如果令牌沒有改變,取回它很快並且不會產生任何顯着的開銷。

(來源:https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#//apple_ref/doc/uid/TP40008194-CH6-SW3

我與APNS經驗,令牌改變任何時候你會爲遠程註冊通知(應用程序重新啓動時)。每次你應該向你的後端重新發送新的令牌,所以它使用最新的令牌發送推送通知。

+0

感謝您的回答。你是正確的,設備令牌不應該被緩存;然而,這不是我在這個問題上討論的。儘管如此,我發現了這個問題(見下面的答案)。簡單的答案是,每次應用程序註冊APNS時,設備標記都不應該改變;雖然它可以改變,但除非應用程序已被刪除然後重新安裝(除此之外,這只是簡單的回答),但APNS通常會向用戶返回相同的標記。我的應用程序沒有緩存令牌。 – Vee