4

I want to send push notification to certain users only.

From what I have gone through in Apple docs. The code to register for push notification is this

- (void)applicationDidFinishLaunching:(UIApplication *)app {
   // other setup tasks here....
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}

// Delegation methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    const void *devTokenBytes = [devToken bytes];
    self.registered = YES;
    [self sendProviderDeviceToken:devTokenBytes]; // custom method
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
    NSLog(@"Error in registration. Error: %@", err);
}

In the method appdidRegisterForRemoteNotif..I see only devToken bytes created and send to the server..but how will I identify which device token belongs to which user. So if my device name is Shubhank's iPhone. How can I send the information that my iPhone is this and this is my device token.

User97693321
  • 3,336
  • 7
  • 45
  • 69
Shubhank
  • 21,721
  • 8
  • 65
  • 83

3 Answers3

6

generally you don't update the apns token on server in the delegate method itself. you save it and update it later when you have the user identified.

You can do it this way:

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

const unsigned *tokenBytes = [deviceToken bytes];
NSString *hexToken = [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])];
[[MyModel sharedModel] setApnsToken:hexToken];

}

with this you saved the apns token in the Model object (MyModel). And later when you have your user identified (by login/sign up or whatever method)

you can call this method

[self sendProvidedDeviceToken: [[MyModel sharedModel] apnsToken] forUserWithId: userId];  //Custom method

This way you have linked the device token with user. Hope this helps!

Manish Ahuja
  • 4,509
  • 3
  • 28
  • 35
  • well thanks that do solve what i was looking... but i have important question now..does token bytes change every time the app starts ??.. – Shubhank Feb 04 '12 at 15:23
  • Although it is not always true that the token will change, but it is always suggested that you update the token every time the app starts. Please upvote/accept the answer if it helped you. – Manish Ahuja Feb 04 '12 at 15:25
  • i will .. but i want to know .this is now confusing me.. lets say the device token is same.. then the device will be re registered on my server.. so i have to develop a mechanism that overwriting works? ..or if the token changes.. then what i will do to the old device name?? – Shubhank Feb 04 '12 at 15:29
  • 1
    yes, you will have to write the overwrite mechanism. because you cannot guarantee that the token will not change. Also, a user might login from one device and then from another device, in that case you'll definitely have to update the apns token for that user – Manish Ahuja Feb 04 '12 at 15:45
  • Just read @JohanKarlsson comment. Tokens change, e.g. by a change in the iOS version, or from time to time. So it is a good idea to check that the token is still the same every time the app starts. – lnjuanj Jan 31 '14 at 09:16
2

You need to send the device name when registering in your custom method. The code should look something like below. You could send along any information that is appropriate for your context, like a username if the application uses some kind username. It is up to you which to decide which information to send to your server that makes a connection between the token and the device.

// Delegation methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    const void *devTokenBytes = [devToken bytes];
    self.registered = YES;
    [self sendProviderDeviceToken:devTokenBytes deviceName:[[UIDevice currentDevice] name]]; // custom method
}
Johan Karlsson
  • 1,136
  • 1
  • 14
  • 37
  • lets say i want the user to input a specific name for his device so i present a text field in which he writes ABC. but i believe the appdidRegisterForRemoteNotif will have been already been called till this occurs.. so can i again register for push notification? – Shubhank Feb 04 '12 at 15:14
  • 2
    It is better to wait for the user to input the name before registering the device. In my current application I wait to do the registration until the user logs in. There is nothing that requires you to register at startup. – Johan Karlsson Feb 04 '12 at 15:16
  • [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; this is called when app starts up..so i believe idRegisterForRemoteNotificati will also be called before i can show my user the text field.... so i believe you are saying that i can call [self sendProvider:Userinput] later .. but how will the server know that this name is coming for this devTokenBytes – Shubhank Feb 04 '12 at 15:21
  • You send your token and username in the same call to the server. The you put these in a database. Whenever you want to send a message to a specific user, you look up the corresponding token. – Johan Karlsson Feb 04 '12 at 16:20
1

It's up to you to send whatever information you need to your own push service.

But an important point: the push token is not the device token (UDID). Push tokens are unique to each app that requests them, and can and do change. If you want to get the device name in addition to that, you can call [[UIDevice currentDevice] name], and post it off to whatever you are using to store your push tokens.

lxt
  • 31,146
  • 5
  • 78
  • 83
  • lets say i want the user to input a specific name for his device so i present a text field in which he writes ABC. but i believe the appdidRegisterForRemoteNotif will have been already been called till this occurs.. so can i again register for push notification? – Shubhank Feb 04 '12 at 15:14
  • No - you will need to hang on to your push token, and then send the device name to your backend service at a later time, after you've received it. – lxt Feb 04 '12 at 15:16
  • [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; this is called when app starts up..so i believe idRegisterForRemoteNotificati will also be called before i can show my user the text field.... so i believe you are saying that i can call [self sendProvider:Userinput] later .. but how will the server know that this name is coming for this devTokenBytes – Shubhank Feb 04 '12 at 15:21