iOS应用每次都会收到一个新的APNS设备令牌

时间:2016-12-05 22:45:41

标签: ios azure push-notification apple-push-notifications token

我使用Azure推送通知,并注意到每次推出应用时APNS都会向我发送新的设备令牌。根据Apple的文档,设备令牌通常应保持不变:

  

每个请求中包含的设备令牌代表其身份   接收通知的设备。 APN使用设备令牌   识别每个独特的应用和设备组合。它也使用它们   验证发送到设备的远程通知的路由。   每次您的应用在设备上运行时,它都会从APN中获取此令牌   并将其转发给您的提供商。您的提供商存储令牌和   在向特定应用和设备发送通知时使用它。   令牌本身是不透明和持久的,仅在a时才会改变   设备的数据和设置将被删除。只有APN可以解码和读取   设备令牌。

然而,基于通过Azure发送的失败消息的常数,我可以推断出我的应用每次启动应用时都会从APNS接收新的设备令牌。有人能告诉我:

  1. 为什么即使我没有更改手机设置或删除应用,我每次都会获得新的设备令牌?

  2. 在上面的Apple摘录中,他们的意思是"删除设备的数据"?究竟是什么数据被APNS用来确定一个独特的应用和设备组合"?

  3. 以下是代码:

    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];
    }
    

2 个答案:

答案 0 :(得分:2)

您可以阅读:

  

永远不要缓存设备令牌;总是在需要时从系统中获取它们。虽然设备令牌对于应用和设备是唯一的,但它们可以随时间而变化。设备令牌可以随时更改,但当用户从备份恢复设备,用户在新设备上安装应用程序以及用户重新安装操作系统时,设备令牌可以保证不同。从系统中获取令牌可确保您始终拥有与APN通信所需的当前令牌。此外,如果令牌没有改变,提取它的速度很快,不会产生任何显着的开销。

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

根据我对APNS的体验,只要您注册远程通知(应用程序重新启动),令牌就会随时更改。每次您应该将新令牌重新发送到后端时,它会使用最新令牌发送推送通知。

答案 1 :(得分:0)

简短回答是,每次应用向APNS注册时,设备令牌都不应更改。来自Apple

  

每个请求中包含的设备令牌代表其身份   接收通知的设备。 APN使用设备令牌   识别每个独特的应用和设备组合。它也使用它们   验证发送到设备的远程通知的路由。   每次您的应用在设备上运行时,它都会从APN中获取此令牌   并将其转发给您的提供商。您的提供商存储令牌和   在向特定应用和设备发送通知时使用它。   令牌本身是不透明和持久的,仅在a时才会改变   设备的数据和设置将被删除。只有APN可以解码和读取   设备令牌

我的应用程序每次都获取一个新的设备令牌,因为我没有正确地将deviceToken的数据类型从Data转换为字符串。 APNS将设备令牌作为类型Data发送,但要将其传递给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就开始向用户返回相同的设备令牌;因此,创建一个“独特的应用程序和设备组合”。