Mike Ross
Mike Ross

Reputation: 2972

Send device token from viewDidLoad to webView Objective C

I have an app in which on viewController i have a simple webView and i am loading my website say https://mywebsite.com

Now i want to send device token to the same website as cookie but for some reason i could not access the deviceToken in viewDidLoad method.

Code is as per below of viewController.m

- (void)viewDidLoad {

     NSUserDefaults *deviceInfo = [NSUserDefaults standardUserDefaults];

     NSString *deviceID = [deviceInfo objectForKey:@"deviceToken"];

    [super viewDidLoad];
    NSURL *url=[NSURL URLWithString:@"http://staging.mywebsite.com"];
    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];


    NSArray * cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies: cookies];

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"deviceToken" forKey:NSHTTPCookieName];
    [cookieProperties setObject:deviceID forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"staging.mywebsite.com" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"staging.mywebsite.com" forKey:NSHTTPCookieOriginURL];

    [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

    [request setHTTPMethod:@"Post"];
    [request setHTTPShouldHandleCookies:YES];
    [request setAllHTTPHeaderFields:headers];


    [_webView loadRequest:request];
}

I have added following code in method didRegisterForRemoteNotificationsWithDeviceToken

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

    NSString *strDevicetoken = [[NSString alloc]initWithFormat:@"%@",[[[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""]];

    NSUserDefaults *deviceInfo = [NSUserDefaults standardUserDefaults];

    [deviceInfo setObject:strDevicetoken forKey:@"deviceToken"];

    [deviceInfo synchronize];

}

It still doesnt work on real device. What wrong am i doing here?

Thank you

Upvotes: 0

Views: 815

Answers (1)

felixwcf
felixwcf

Reputation: 2105

Your current situation is when you register for remote notification in app delegate and before didRegisterForRemoteNotificationsWithDeviceToken is called, you have already initiate your view controller (VC) and viewDidLoad method is being called before you get the device token.

Your app flow should be like this

i. In app delegate didFinishLaunchingWithOptions method, register remote notification.

ii. Within a second, in didRegisterForRemoteNotificationsWithDeviceToken callback function, you should receive the device token.

iii. If you initiate your view controller in app delegate, you can make a public function in your view controller:

- (void)requestWebViewWithToken:(NSString *)token {
    // You code - storing token in cookies and request webview. 
}

iv. Call the function in didRegisterForRemoteNotificationsWithDeviceToken ONLY when you get the token. There's so many options. You can use NSNotificationCenter, custom delegate, public method (as mentioned above), or static method.

"But i think reloading UIwebView doesnt seem like good programming. Website inside webview will be loaded first and after receiving deviceToken reloaded,dont like the idea of that"

Reloading webview when you need to, not being redundant, is acceptable. For your case, you can show and animate activity indicator view (loading indicator) in viewDidLoad.

Load the webview only when you receive the token. It just take 1 second to get the token, so waiting to load the webview after you get the token won't causing user experience defect.

Lastly, you might need to handle the situation where user did not turn on to receive push notification, or no Internet connection etc...


Solution:

  1. In AppDelegate.m, in your didRegisterForRemoteNotificationsWithDeviceToken delegate,

    [[NSNotificationCenter defaultCenter] postNotificationName:@"device_token_notification"
                                                        object:nil
                                                      userInfo:@{@"token":@"8057b9be2a0caa8802034369fc6035aac9c577180xxxx"}];
    
  2. In your vc which contains the webview, in your viewDidLoad method, add this code:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(requestWebView:)
                                             name:@"device_token_notification"
                                           object:nil];
    

and create the method

- (void)requestWebView:(NSNotification *)noti {
    NSDictionary *dict = [noti userInfo];
    NSString *deviceToken = dict[@"token"];

    // Store token into cookies.
    // Request your web.
}

Remember to remove the receiver when you don't need it.

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:@"device_token_notification"];
}

Upvotes: 1

Related Questions