10

I have read a lot of tutorials for this and i just wanted ti know if this is right way to do this

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    NSLog(@"My token is: %@", deviceToken);

    NSString* newToken = [deviceToken description];

    newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""]; 


    NSString *urlString = [NSString stringWithFormat:@"http://myhost.com./filecreate.php?token=%@",newToken];

    NSURL *url = [[NSURL alloc] initWithString:urlString];

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

    NSData *urlData;
    NSURLResponse *response;
    urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];

}

any advices are more then welcomed.

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{

    const char* data = [deviceToken bytes];
    NSMutableString* token = [NSMutableString string];

    for (int i = 0; i < [deviceToken length]; i++) {
        [token appendFormat:@"%02.2hhX", data[i]];
    }


    NSString *urlString = [NSString stringWithFormat:@"http://myhost.com/filecreate.php?token=%@",token];

    NSURL *url = [[NSURL alloc] initWithString:urlString];

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];   
    NSData *urlData;
    NSURLResponse *response;
    urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];

}

My application works with both codes, but what's the right way?

Spire
  • 1,055
  • 2
  • 17
  • 47
  • 1
    looks fine, but, i would 1, add error recovery mechanism (if the request fails you will lose your token!) and b, use asynchronous request. – mja Sep 20 '11 at 09:05
  • 1
    asynchronous? how do you mean.Please give me some guide lines for the error recovery mechanism also. The code works but I was wondering if this is the right way, cause I have read somewhere that `NSString* newToken = [deviceToken description];` this is not the right way to get data into string – Spire Sep 20 '11 at 11:23
  • Does your code work? I did the same thing but my device token became `(null)` when I send it to the server? –  Mar 18 '13 at 10:08
  • 1
    @tnylee are you getting it in the NSLog?Try printing "urlString" just before sending to server and see. Print the response to see what happens on the server side. – Spire Mar 18 '13 at 13:05
  • @Spire Yes I am getting it in NSLog, I removed the "<" ">" " " signs too. It still is `(null)`. –  Mar 19 '13 at 03:13
  • @Spire I had it working! I forgot to put "+" in between for spaces. Thanks for trying to help! :D –  Mar 19 '13 at 03:23
  • @tnylee No prob, glad you solve it – Spire Mar 19 '13 at 08:42

2 Answers2

18

As mja said in comments, it's better to add error recovery mechanism (if the request fails you will lose your token) and use asynchronous request (send token in background)

In your AppDelegate.m:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    NSString * token = [NSString stringWithFormat:@"%@", deviceToken];
    //Format token as you need:
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
    token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];

    [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"apnsToken"]; //save token to resend it if request fails
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"apnsTokenSentSuccessfully"]; // set flag for request status
    [DataUpdater sendUserToken]; //send token
}

To send token create new class (or use one of existing):
DataUpdater.h

#import <Foundation/Foundation.h>

@interface DataUpdater : NSObject     
+ (void)sendUserToken;
@end

DataUpdater.m

#import "DataUpdater.h"

@implementation DataUpdater

+ (void)sendUserToken {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"apnsTokenSentSuccessfully"]) {
        NSLog(@"apnsTokenSentSuccessfully already");
        return;
    }

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myhost.com/filecreate.php?token=%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"apnsToken"]]]; //set here your URL

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         if (error == nil) {
             [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"apnsTokenSentSuccessfully"];
             NSLog(@"Token is being sent successfully");
             //you can check server response here if you need
         }
     }];
}

@end

Then you can call [DataUpdater sendUserToken]; in your controllers when internet connection appears, or periodically, or in -(void)viewDidLoad or -(void)viewWillAppear methods

My advises:
1) I use AFNetworking to send async request and check server JSON response
2) Some times it's better to use services such as Parse to work with push notifications

a_alexeev
  • 278
  • 5
  • 6
  • Thx dude but this is very very old question. Ill accept the answer, it might benefit someone. – Spire Jul 24 '13 at 13:41
  • 3
    I think you should call [synchronize](https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/nsuserdefaults_class/reference/reference.html#//apple_ref/occ/instm/NSUserDefaults/synchronize) after storing the info. – nsacerdote Jul 11 '14 at 11:33
0

In didFinishLaunchingWithOptions method

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

After doing above lines of code ,add the method below

#pragma mark -
#pragma mark Push Notifications
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString  *token_string = [[[[deviceToken description]    stringByReplacingOccurrencesOfString:@"<"withString:@""]
                            stringByReplacingOccurrencesOfString:@">" withString:@""]
                           stringByReplacingOccurrencesOfString: @" " withString: @""];
NSString* strURL = [NSString stringWithFormat:@"http://www.sample.com?device_token=%@&type=IOS",token_string];
strURL=[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",strURL);
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSLog(@"content---%@", fileData);
}
Rahul K Rajan
  • 776
  • 10
  • 19