Get device token for push notification

IosIphonePush NotificationApple Push-NotificationsAppdelegate

Ios Problem Overview


I am working on push notifications. I wrote the following code for fetching a device token.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    NSLog(@"Registering for push notifications...");    
	[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    
    return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
	NSLog(@"This is device token%@", deviceToken);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
    NSString *str = [NSString stringWithFormat: @"Error: %@", err];
    NSLog(@"Error %@",err);    
}

I am able to run application on device successfully but not able to get the device id on console.

I have no issues with certification and provisioning profiles.

Ios Solutions


Solution 1 - Ios

NOTE: The below solution no longer works on iOS 13+ devices - it will return garbage data.

Please use following code instead:

+ (NSString *)hexadecimalStringFromData:(NSData *)data
{
  NSUInteger dataLength = data.length;
  if (dataLength == 0) {
    return nil;
  }

  const unsigned char *dataBuffer = (const unsigned char *)data.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  return [hexString copy];
}

Solution that worked prior to iOS 13:

Objective-C

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"this will return '32 bytes' in iOS 13+ rather than the token", token);
} 

Swift 3.0

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("this will return '32 bytes' in iOS 13+ rather than the token \(tokenString)")
}

Solution 2 - Ios

To get Token Device you can do by some steps:

  1. Enable APNS (Apple Push Notification Service) for both Developer Certification and Distribute Certification, then redownload those two file.

  2. Redownload both Developer Provisioning and Distribute Provisioning file.

  3. In Xcode interface: setting provisioning for PROJECT and TARGETS with two file provisioning have download.

  4. Finally, you need to add the code below in AppDelegate file to get Token Device (note: run app in real device).

    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      [self.window addSubview:viewController.view]; [self.window makeKeyAndVisible];

      NSLog(@"Registering for push notifications...");
      [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; return YES; }

    • (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken]; NSLog(@"%@", str); }

    • (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSString *str = [NSString stringWithFormat: @"Error: %@", err]; NSLog(@"%@",str); }

Solution 3 - Ios

Using description as many of these answers suggest is the wrong approach - even if you get it to work, it will break in iOS 13+.

Instead you should ensure you use the actual binary data, not simply a description of it. Andrey Gagan addressed the Objective C solution quite well, but fortunately it's much simpler in swift:

Swift 4.2 works in iOS 13+

// credit to NSHipster (see link above)
// format specifier produces a zero-padded, 2-digit hexadecimal representation
let deviceTokenString = deviceToken.map { String(format: "%02x", $0) }.joined()

Solution 4 - Ios

Objective C for iOS 13+, courtesy of Wasif Saood's answer

Copy and paste below code into AppDelegate.m to print the device APN token.

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  NSUInteger dataLength = deviceToken.length;
  if (dataLength == 0) {
    return;
  }
  const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  NSLog(@"APN token:%@", hexString);
}

Solution 5 - Ios

Following code is use for the retrive the device token.

	// Prepare the Device Token for Registration (remove spaces and < >)
	NSString *devToken = [[[[deviceToken description] 
							stringByReplacingOccurrencesOfString:@"<"withString:@""] 
						   stringByReplacingOccurrencesOfString:@">" withString:@""] 
						  stringByReplacingOccurrencesOfString: @" " withString: @""];
	
    
    NSString *str = [NSString 
                     stringWithFormat:@"Device Token=%@",devToken];
    UIAlertView *alertCtr = [[[UIAlertView alloc] initWithTitle:@"Token is " message:devToken delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
	[alertCtr show];
    NSLog(@"device token - %@",str);

Solution 6 - Ios

And the Swift version of the Wasif's answer:

Swift 2.x

var token = deviceToken.description.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
token = token.stringByReplacingOccurrencesOfString(" ", withString: "")
print("Token is \(token)")

Update for Swift 3

let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()

Solution 7 - Ios

Starting from iOS 13 Apple has changed [deviceToken description]output. Now it is like this {length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc} which is incorrect for device token.

I suggest to use this code snippet to resolve a problem:

+ (NSString *)stringFromDeviceToken:(NSData *)deviceToken {
    NSUInteger length = deviceToken.length;
    if (length == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(length * 2)];
    for (int i = 0; i < length; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }
    return [hexString copy];
}

It will work for iOS13 and lower.

Solution 8 - Ios

If you are still not getting device token, try putting following code so to register your device for push notification.

It will also work on ios8 or more.

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
    
    if ([UIApplication respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound
                                                                                 categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         UIRemoteNotificationTypeBadge |
         UIRemoteNotificationTypeAlert |
         UIRemoteNotificationTypeSound];
        
    }
#else
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     UIRemoteNotificationTypeBadge |
     UIRemoteNotificationTypeAlert |
     UIRemoteNotificationTypeSound];
    
#endif

Solution 9 - Ios

In your AppDelegate, in the didRegisterForRemoteNotificationsWithDeviceToken method:

Updated for Swift:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print("\(deviceToken.reduce("") { $0 + String(format: "%02.2hhx", arguments: [$1]) })")
}

Solution 10 - Ios

Get device token in Swift 3

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

    print("Device token: \(deviceTokenString)")

}

Solution 11 - Ios

Swift 4 This works for me:

Step 1 into TARGETS Click on add capability and select Push Notifications

Step 2 in AppDelegate.swift add the following code:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound]) { (didAllow, error) in
            
        }
        UIApplication.shared.registerForRemoteNotifications()
        
        return true
    }
    
    //Get device token
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
    {
        let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
        
        print("The token: \(tokenString)")
    }

Solution 12 - Ios

For Objective-C

There are some changes for the iOS 13 push token

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = @"";
        if (@available(iOS 13, *)) {
        NSUInteger length = deviceToken.length;
        if (length == 0) {
            token = @"";
        }
        const unsigned char *buffer = deviceToken.bytes;
        NSMutableString *actualToken  = [NSMutableString stringWithCapacity:(length * 2)];
        for (int i = 0; i < length; ++i) {
            [actualToken appendFormat:@"%02x", buffer[i]];
        }
        token = [actualToken copy];
        } else {
            token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
                token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
        }
        NSLog(@"My token is: %@", token);
}

Solution 13 - Ios

In a build setting set code signing Provision Profile if you have APN Enable certificate then you will definitely get the token id. and remove

Provision Profile : Automatic

and set to

Provision Profile : Your provision profile certificate.

Solution 14 - Ios

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            
    let tokenParts = deviceToken.map { data -> String in
        return String(format: "%02.2hhx", data)
        }
    let token = tokenParts.joined()
            
    print("Token\(token)")
}

Solution 15 - Ios

In order to get the device token use following code but you can get the device token only using physical device. If you have mandatory to send the device token then while using simulator you can put the below condition.

  if(!(TARGET_IPHONE_SIMULATOR))
    {
        [infoDict setValue:[[NSUserDefaults standardUserDefaults] valueForKey:@"DeviceToken"] forKey:@"device_id"];
    }
    else
    {
        [infoDict setValue:@"e79c2b66222a956ce04625b22e3cad3a63e91f34b1a21213a458fadb2b459385" forKey:@"device_id"];
    }



- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    NSLog(@"My token is: %@", deviceToken);
    NSString * deviceTokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""]   stringByReplacingOccurrencesOfString: @" " withString: @""];
    NSLog(@"the generated device token string is : %@",deviceTokenString);
    [[NSUserDefaults standardUserDefaults] setObject:deviceTokenString forKey:@"DeviceToken"];
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjagzzzView Question on Stackoverflow
Solution 1 - IosWasif SaoodView Answer on Stackoverflow
Solution 2 - IosBkillnestView Answer on Stackoverflow
Solution 3 - Ioschris stamperView Answer on Stackoverflow
Solution 4 - IosJake CroninView Answer on Stackoverflow
Solution 5 - IosNimit ParekhView Answer on Stackoverflow
Solution 6 - IosAntoineView Answer on Stackoverflow
Solution 7 - IosAndrey GaganView Answer on Stackoverflow
Solution 8 - IosNileshView Answer on Stackoverflow
Solution 9 - IosvfnView Answer on Stackoverflow
Solution 10 - IosSedat YView Answer on Stackoverflow
Solution 11 - IosJames RyanView Answer on Stackoverflow
Solution 12 - IosRuchin SomalView Answer on Stackoverflow
Solution 13 - IoskalpeshView Answer on Stackoverflow
Solution 14 - IosAmit GuptaView Answer on Stackoverflow
Solution 15 - IosYashView Answer on Stackoverflow