2016-12-05 62 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