13 Replies
      Latest reply on May 7, 2020 1:01 PM by asengupta
      trevr2 Level 1 Level 1 (0 points)

        Hi guys

         

        Just been testing our app under iOS13 and I've noticed something odd with VOIP push notifications when getting the token

         

        When I obtain the push token to send to the server, the value looks completely wrong under iOS13

         

        In iOS12 and before this would be a typical token that was returned from credentials.token

         

        <124686a5 556a72ca d808f572 00c323b9 3eff9285 92445590 3225757d b83997ba>

         

        Whereas now under iOS 13, the same call returns this (including the brackets, dots and text)

         

        {length = 32, bytes = 0xd3d997af 967d1f43 b405374a 13394d2f ... 28f10282 14af515f }

         

        Of course when I pass this to the server to send on to Apple to send for the push notification, I get the following response from the Apple server

         

        Invalid Device Token Format Error sending Apple Push Notification Device Token has a length of [69] and not the required 64 bytes!

         

        Does anybody know what is going on here

         

        Hope you can help

         

        Trevor

        • Re: iOS13 PKPushCredentials broken
          trevr2 Level 1 Level 1 (0 points)

          So it turns out that the description method on NSData now returns different results.

           

          Originally my code was as follows....

           

          -(void)pushRegistry:(PKPushRegistry *)regsitry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {

              NSData* deviceToken = credentials.token;

              NSString* tkn = [NSString stringWithFormat:@"%@", deviceToken];

           

          This gave me a token of something like

           

          <124686a5 556a72ca d808f572 00c323b9 3eff9285 92445590 3225757d b83967be>

           

          which I could then remove the chevrons and spaces and use for the push notification.

           

          But now, the same code gives me the following string

           

          {length = 32, bytes = 0xd3d997af 967d1f43 b405374a 13394d2f ... 28f10282 14af515f }

           

          After spotting this I'm now using

           

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

              const unsigned *tokenBytes = [deviceToken bytes];

              NSString *tkn = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",

                                   ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),

                                   ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),

                                   ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

           

          which gives me the correct string for the token for push notification

           

          So the format of the [... description] has changed under iOS13, didn't see that documented anyway!

           

          Before anybody mentions, yes, it was a school boy error to use the description method

           

          Hope this helps somebody

           

          Trev

            • Re: iOS13 PKPushCredentials broken
              bweiss Level 1 Level 1 (0 points)

              Which SDK did you use to Build the App.

              I have done similar things with description of data but did not seen an error with iOS 12 build on an iOS 13 device.

              • Re: iOS13 PKPushCredentials broken
                nobiliweb Level 1 Level 1 (0 points)

                When i can find this source code? What the file?

                • Re: iOS13 PKPushCredentials broken
                  asengupta Level 1 Level 1 (0 points)

                  You are again doing a dangerous mistake. APNS token length is not fixed and can change over time.

                  The following code or something similar can be a feasible solution that doesn't depend on the assumed and hardcoded token length:

                   

                  constchar *data = [deviceToken bytes];
                  NSMutableString *token = [NSMutableString new];
                  for (NSUInteger i = 0; i < [deviceToken length]; i++) {
                      [token appendFormat:@"%02.2hhX", data[i]];
                  }
                  
                  self.application.devicePushNotificationToken = token;

                   

                  And by no means any developer should use the description method of any object unless that is explicitly overriden and you know the expected outcome. That method has merely been put for debugging purpose and can change without any documentation update.

                • Re: iOS13 PKPushCredentials broken
                  tahakirca Level 1 Level 1 (0 points)

                  we have same issue. Some of ios 13 device token string broken but some of is correct format. Do you know any solution or update for this problem?

                   

                  Update: If user already installed app, push token return correct format otherwise push token string broken same with trevr2 example.

                  {length=32,bytes=0x3d1697e3f8d9d1db7402b4d043e...55103f58353a8896}

                    • Re: iOS13 PKPushCredentials broken
                      trevr2 Level 1 Level 1 (0 points)

                      So our project has a deployment Target of iOS11.0

                       

                      The solution that worked for me was to no longer use the description method, this is always dangerous as this could change (and obviously has). I've changed our code to that as shown in my second post and this works fine on both ios12 and ios13

                    • Re: iOS13 PKPushCredentials broken
                      billycb Level 1 Level 1 (0 points)

                      Hi guys

                       

                      I just found a temporal solution but I don't know it is correct, try to change [.... description] to [... debugDescription] only for iOS13, similar like this:

                       

                      - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                          NSString *tokenDescription = [[[UIDevice currentDevice] systemVersion] floatValue] >= 13.0 ? [deviceToken debugDescription] : [deviceToken description];
                          NSString *token = [tokenDescription stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
                          token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
                          ......
                      }
                      

                       

                      As you said, it seems that the [... description] format has changed in iOS 13, but there is no documentation about that!

                      • Re: iOS13 PKPushCredentials broken
                        vasyl.liutikov Level 1 Level 1 (0 points)

                        you could try Facebook' lib solution.

                        https://github.com/facebook/facebook-objc-sdk/blob/master/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m#L571

                        + (NSString *)hexadecimalStringFromData:(NSData *)data
                        {
                            NSUInteger dataLength = data.length;
                            if (dataLength == 0) {
                                return nil;
                            }
                            
                            const unsigned char *dataBuffer = data.bytes;
                            NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
                            for (int i = 0; i < dataLength; ++i) {
                                [hexString appendFormat:@"%02x", dataBuffer[i]];
                            }
                            return [hexString copy];
                        }
                        
                        
                        • Re: iOS13 PKPushCredentials broken
                          douglasfromorlando Level 1 Level 1 (0 points)

                          I have the same issue. Also, I don't think it is safe to expect the device tokens to always be 32 bytes. I found this from raywenderlich.com that handles the "{length = 32, ...}" description scenario...

                           

                          let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }

                          deviceTokenString = tokenParts.joined()

                           

                          However, it doesn't work for the other tokens with description "<... >"

                          • Re: iOS13 PKPushCredentials broken
                            gdeglin Level 1 Level 1 (0 points)

                            This is a really serious change that will break a lot of apps. The "description" method has been the documented way to get the push token in dozens of books, hundreds of online tutorials, SDKs, etc.

                             

                            For example, this StackOverflow answer guides readers towards this implementation and has over 160,000 views: https://stackoverflow.com/questions/8798725/get-device-token-for-push-notification/8798981#8798981

                             

                            This problem was introduced in iOS 13 Beta 2 and doesn't appear to have affected Beta 1. So even though we tested the beta, we didn't notice until just now.

                            • Re: iOS13 PKPushCredentials broken
                              DanK1985 Level 1 Level 1 (0 points)

                              We are getting same error. Some times device token call returns including the brackets, dots and text.

                              • Re: iOS13 PKPushCredentials broken
                                ARMistice Level 1 Level 1 (0 points)

                                ???

                                Why is this change happening? I am really puzzled, as already mentioned it was the described (in many many places) way to get the token.

                                Do we have to update all our apps and resubmit it to the store? Or will there be a change back in 13.x?

                                 

                                (Already wondered why I get less Notifications with 13.1)