How to share users device token in ViewController

990 views Asked by At

I am trying to find a way to make it possible for the user to find their device token (for debugging reasons).


I have tried this:

AppDelegate.h

...
@interface MyAppDelegate : UIResponder <UIApplicationDelegate> {
    NSString *token;
}
@property (nonatomic, retain) NSString *token;
...

AppDelegate.m

...

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    _token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    _token = [_token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSUInteger lenthtotes = [_token length];
    NSUInteger req = 64;

    if (lenthtotes == req){
        NSLog(@"uploaded token: %@", _token);
        upload_token = _token;
    } else {
        _token = @"";
    }
    ...

ViewController.m

NSString *token;
- (void)viewDidLoad
{
    [super viewDidLoad];
    MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
    token = appDelegate.token;
    NSLog(token);
...

The log within the AppDelegate works fine and returns the device token. But the log inside the ViewController returns nothing how come ?

2

There are 2 answers

1
klefevre On BEST ANSWER

It is normal that you can't retrieve the token this way because in the viewDidLoad method of your view controller you didn't get your token yet. Instead of retrieving it from the AppDelegate, you should push it. I would use a notification for that :

AppDelegate.m

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [_token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSUInteger lenthtotes = [_token length];
    NSUInteger req = 64;
    if (lenthtotes == req) {
        NSLog(@"uploaded token: %@", token);
        NSNotification *notif = [NSNotification notificationWithName:@"NEW_TOKEN_AVAILABLE" object:token];
        [[NSNotificationCenter defaultCenter] postNotification:notif];
    }
    ...
}

ViewController.m

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(tokenAvailableNotification:)
                                                 name:@"NEW_TOKEN_AVAILABLE"
                                               object:nil];
}

- (void)tokenAvailableNotification:(NSNotification *)notification {
    NSString *token = (NSString *)notification.object;
    NSLog(@"new token available : %@", token);
}

- (void)dealloc {
    [NSNotificationCenter defaultCenter] removeObserver:self];
}
0
emma ray On

The simplest approach is to grab it from the notification delegate method:

@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
{
    // No need to define backing variables
}

@property (nonatomic, retain) NSString *token;

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    self.token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
} 

Note that you must be compiling with the provisioning profile that's associated with your APNS-enabled App ID. If APNS is not properly configured, you may not receive a token.

As a side note, there is no need to define instance variables when using properties. The compiler will handle setting up backing variables, and managing all of that; you simply define the @property and access it through the pre-defined setters and getters (self.variableName).