Get device token for push notification
Asked Answered
A

15

94

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.

Aleris answered 10/1, 2012 at 4:54 Comment(11)
Did you follow all the steps? If you are not having any problem with certification and provision as well as code then you must be doing some small mistake. Like..tell me, are you running the app on real device attaching the same with your system? Also are you noticing whether you are getting the device token in console log or not? Have you enable Push notification in iPhone?Aronoff
I am not able to get device token on console log.Aleris
I am running the app on real device with out any error.Aleris
Did you enable APNS as shown in the link on iPhone?Aronoff
yes i enabled APNS..but the device token is not able to fetch on cosoleAleris
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { } method is not running at all. when i see in settings my application is enable for push notification that means it is registered but m not able to see the device token on console.Aleris
Do 1 thing : check this link : mobiforge.com/developing/story/… Then follow all the steps accordingly. Your problem must resolveAronoff
What you mean by console? Simulator? BTW push notification wont work on simulatorMephistopheles
Also try printing the value of strMephistopheles
Unclocked iphone are able to get device token?Aleris
yes..mine is also unlocked and I am getting the same.Aronoff
V
167

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)")
}
Veliger answered 10/1, 2012 at 5:32 Comment(14)
Then please check your provisioning profile,it should be of that app ID by which you have created your ssl certifcate for push notification.Veliger
you need to add the code into AppDelegate file @jagzzzSagamore
For those interested in a code example writtent in Swift: gist.github.com/sawapi/a7cee65e4ad95578044dEvermore
Careful, using the "description" property no longer works: #39495891Murder
You have to provide the Notification Settings also, without it didn't worked for me. For Swift 4 with xCode 9.x you can also check this code snipped. gist.github.com/sawapi/a7cee65e4ad95578044d#gistcomment-1458043Immovable
Objective C method is broken from Xcode 11 onwards. I have edited the answer as it is widely accepted answer.Whew
I posted an answer of how to write this in xamarin/c#: #58027844Assuan
@Whew I had uploaded my build using Xcode 10.3 and it is live. As per your statement, the Objective C method is going to broken onward XCode 11 but what I can see in our database it is showing the data length instead of a correct string of apns token. So I just want to know that, Is it depending on Xcode version or iOS version (i.e 13.*)?Piefer
The updated iOS 13+ solution would be better if it was copy+pasteable! It is currently only a partial solution, and tough to use by those who do not understand Obj C syntaxImperfect
I think this sentence in the linked nshipster article should be added to the answer to make the situation a bit more clear: The part "... this approach won’t work in apps compiled with the iOS 13 SDK". This is a bit different to "The below solution no longer works on iOS 13+ devices" So an app that needs no update with xCode 11 and iOS13 SDK can still send a valid token. Or am I wrong here?Coplanar
@JakeCronin I agree with you. Well, after a lot of struggling, I found out how to do it: in your AppDelegate.m didRegisterForRemoteNotificationsWithDeviceToken method, just pass globally the NSData deviceToken, then use the ObjectiveC example with it. In other words, stop using the NSString description.Archeozoic
What about swift ios +13?Fakir
Just wanted to give the credit of the iOS 13+ solution to Andrey Gagan below.Settlings
For Swift, to prevent unnecessary memory allocations: let tokenString = deviceToken.reduce(into: "") { $0.append(String(format: "%02X", $1)) }Pliam
T
14

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()
Timmerman answered 17/9, 2019 at 13:37 Comment(0)
M
13

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);
}
Melleta answered 27/5, 2013 at 3:56 Comment(0)
I
9

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);
}
Imperfect answered 28/9, 2019 at 19:59 Comment(0)
S
6

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.

Sedge answered 10/9, 2019 at 7:21 Comment(1)
FYI - any answer that ever used description was always wrong. And this is only one possible solution to convert the token to a string. A much simpler solution is to convert the NSData to an NSString using standard base64 encoding.Ashcan
S
5

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()
Syllogism answered 30/8, 2016 at 12:33 Comment(1)
Never use description on binary data (see any other answer)Timmerman
B
4

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);
Berkshire answered 10/1, 2012 at 4:58 Comment(1)
This has never been the correct solution. Never base anything on the description.Ashcan
P
4

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
Pietro answered 10/4, 2015 at 9:50 Comment(0)
F
2

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)")

}
Foliated answered 29/11, 2016 at 22:9 Comment(0)
T
1

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]) })")
}
Tutelary answered 26/11, 2014 at 5:9 Comment(0)
R
0

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)")
    }
Resourceful answered 18/8, 2020 at 0:22 Comment(0)
S
0

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);
}
Stig answered 31/3, 2021 at 9:45 Comment(0)
I
0

Use the following code to get device token:

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

You can reach Netmera Guide for push payloads and to get more push notification information.

Incombustible answered 11/7, 2023 at 8:27 Comment(0)
W
-2
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)")
}
Wolver answered 3/2, 2020 at 10:15 Comment(0)
C
-4

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"];
}
Culbreth answered 28/12, 2017 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.