Saving the DeviceToken for Later Use in Apple Push Notification Services

13,549

Solution 1

I suggest you to convert token to string in this way:

self.dToken = [[[deviceToken description]
                    stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] 
                    stringByReplacingOccurrencesOfString:@" " 
                    withString:@""];

UPDATED: As many people mentioned it is better to use next approach to convert NSData * to NSString *:

@implementation NSData (Conversion)
- (NSString *)hexadecimalString
{
  const unsigned char *dataBuffer = (const unsigned char *)[self bytes];

  if (!dataBuffer) {
    return [NSString string];
  }

  NSUInteger          dataLength  = [self length];
  NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];

  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02lx", (unsigned long)dataBuffer[i]];
  }

  return hexString;
}
@end

Solution 2

From the discussion at Best way to serialize an NSData into a hexadeximal string, here is a better way to do it. Is longer, but your code will be future-proof if Apple changes the way NSData emit debugger descriptions.

Extend NSData as follows:

@implementation NSData (Hex)
- (NSString*)hexString {
    unichar* hexChars = (unichar*)malloc(sizeof(unichar) * (self.length*2));
    unsigned char* bytes = (unsigned char*)self.bytes;
    for (NSUInteger i = 0; i < self.length; i++) {
        unichar c = bytes[i] / 16;
        if (c < 10) c += '0';
        else c += 'A' - 10;
        hexChars[i*2] = c;
        c = bytes[i] % 16;
        if (c < 10) c += '0';
        else c += 'A' - 10;
        hexChars[i*2+1] = c;
    }
    NSString* retVal = [[NSString alloc] initWithCharactersNoCopy:hexChars
                                                           length:self.length*2 
                                                     freeWhenDone:YES];
    return [retVal autorelease];
}
@end

Solution 3

I know that this is an old question and that this may be new information that has come up since then, but I'd just like to point something out to all of the people who are claiming that using the description method is a really bad idea. In most cases, you'd be exactly right. The description property is generally just used for debugging, but for the NSData class, it's specifically defined as returning a hexadecimal representation of the receivers contents which is exactly what is needed here. Since Apple has put it in their documentation, I think you're pretty safe as far as them changing it.

This can be found in the NSData Class Reference here: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html

Share:
13,549
azamsharp
Author by

azamsharp

Mohammad Azam is an iOS Instructor at DigitalCrafts. Before joining DigitalCrafts Azam worked as a senior mobile developer at Blinds.com, A Home Depot company. Azam led the mobile team at Blinds.com to develop the Home Depot blinds/shades online experience. Previously, Azam has worked as a team lead for many large companies including Schlumberger, Baker Hughes, AIG and VALIC. Azam has also published 8-10 personal apps to the App Store, including Vegetable Tree - Gardening Guide which was featured by Apple as the best gardening app in the App Store. Azam is also active on YouTube and maintains his popular channel "AzamSharp" where he shares his iOS knowledge. Azam is also a Udemy instructor where he has published courses on "Swift 2.0" and "iOS MapKit Development Using Swift Language". Azam also frequently contributes iOS articles to the Code Magazine and talks at different iOS conferences all around the country. Before entering the iOS community Azam was an active member of the Microsoft .NET community. Azam was also awarded Microsoft MVP award due to his contributions in the .NET community. Azam is also an instructor on Udemy with more than 2000 students. Azam has earned perfect ratings for his courses on Udemy. You can check out Azam's courses using the link below: http://www.azamsharp.com/courses/ When not developing iOS applications Azam likes to spend time with his family and plan his next trip to the unknown corners of the world.

Updated on June 03, 2022

Comments

  • azamsharp
    azamsharp about 2 years

    In my iPhone app I am getting the device token from Apple which I am assigning a public property inside the Delegate file as shown below:

    - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
    {
       self.dToken = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding]; 
    }
    

    The dToken property is declared as shown below:

    NSString *dToken;
    
    @property (nonatomic,retain) NSString *dToken;
    

    But when I try to retrieve the device token from another file I get the null value.

    +(NSString *) getDeviceToken
    {
      NSString *deviceToken = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] dToken];
    
        NSLog(@" getDeviceToken = %@",deviceToken);  // This prints NULL
    
        return deviceToken; 
    
    }
    

    What am I doing wrong?

  • azamsharp
    azamsharp over 12 years
    Actually it is the getDeviceToken method which is not able to retrieve the value of dToken.
  • Nekto
    Nekto over 12 years
    Are you sure that didRegisterForRemoteNotificationsWithDeviceToken is called and dToken is initialized?
  • azamsharp
    azamsharp over 12 years
    Actually, your code for deviceToken description did the trick. Thank you very much!
  • Juan Carlos Méndez
    Juan Carlos Méndez about 12 years
    The code above works (at least for now) but is not good form. Reading the description property should not be considered an acceptable mechanism for HEX encoding the string, as it is meant for debugging description, not for encoding! See stackoverflow.com/questions/1305225/… for more correct ways to serialize the token
  • Brian Sachetta
    Brian Sachetta over 8 years
    "Since Apple has put it in their documentation, I think you're pretty safe as far as them changing it" ... Wishful thinking.
  • art-divin
    art-divin over 7 years
    @Nekto thanks for your answer. An improvement would be to return non-mutable copy of NSString , as signature suggests.
  • Nekto
    Nekto over 7 years
    @art-divin -- that is what a caller should care about otherwise you might have a useless copy operation. You can return mutable objects instead of immutable when designing APIs.