I have the following code running to handle a push notification -
I receive the notification -> tap on it -> and then performing a jsCallBack -> passing the custom data as parameters to a JS function.
but this works only when the app is running in background or foreground.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//Handle notification when the user click it while app is running in background or foreground.
[[Pushbots sharedInstance] receivedPush:userInfo];
//Get Custom field data
NSString* Value1 = [userInfo objectForKey:@"customval1"];
NSString* Value2 = [userInfo objectForKey:@"customval1"];
NSLog(@"%@", Value1);
NSLog(@"%@", Value2);
NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
NSLog(@"%@", jsCallBack);
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
}
I read posts in SO and few other blogs that didFinishLaunchingWithOptions
is something that would help me handle the notification when the app is not running at all.
This link has info but am not sure about the implementation for my scenario.
Please could someone help me on how to use didFinishLaunchingWithOptions
in my case? What all I need is to get the custom data fields, pass them to my JSCallBack even when the app is not running.
Should I have both didReceiveRemoteNotification
and didFinishLaunchingWithOptions
in my delegate.m? Also, when I am also using didFinishLaunchingWithOptions
in my delegate.m, what changes should I make in delegate.h?
UPDATE 1: I understood that, when the app is terminated, one cannot get access to the payload. And, when app is in foreground or background, it is the didReceiveRemoteNotification
that works when there is a push notification.
But, I am not able to invoke my JS callback function when I received the notification and I tapped on it while the app is in background.
I need some help on how to handle this.
You need to do following code in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo) {
[self application:application didReceiveRemoteNotification:userInfo];
}
First I think you can not access all the notifications which came when the app was not running. You only get access to the the notification which you clicked to activate the app. I think this thread here explains it very well
didReceiveRemoteNotification when in background
For your scenario I think you would need to somehow keep the counter on server side and when the app is active then exchange it and retrieve the ones missed by the app.
Now for the code to handle your case when app is launched you can do this in didFinishLaunchingWithOptions
and I think you would need to leave your existing function didReceiveRemoteNotification
because they will be called when a notification is received when app is running in background (is not terminated)
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif)
{
NSDictionary *userInfo;
NSString* Value1 = [userInfo objectForKey:@"customval1"];
NSString* Value2 = [userInfo objectForKey:@"customval1"];
NSLog(@"%@", Value1);
NSLog(@"%@", Value2);
NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
NSLog(@"%@", jsCallBack);
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
[viewController displayItem:itemName]; // custom method
NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
NSLog(@"%@", jsCallBack);
[self.viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
}
return YES;
}
This works for me, as required in my question + the UPDATE-
If the app is in foreground or in background -
//app is in background/foreground
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[Pushbots sharedInstance] receivedPush:userInfo]; //Using Pushbots notification platform - a 3rd party push platform
NSString* Value1 = [userInfo objectForKey:@"val1"];
NSString* Value2 = [userInfo objectForKey:@"val2"];
NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
// If the app is in the foreground just execute the javascript
if ( application.applicationState == UIApplicationStateActive ) {
[self.viewController.webView stringByEvaluatingJavaScriptFromString: jsCallBack];
} else {
// If the app is in background, then force to execute the js code on the main thread
[self.viewController.webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:jsCallBack waitUntilDone:NO]
}
}
If the app is in closed state,
add this in didFinishLaunchingWithOptions
//Don't remove the existing code, just paste this before the return YES
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cordovaDidLoad) name:CDVPageDidLoadNotification object:self.viewController.webView];
if (launchOptions) { //check if launchOptions is not nil
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
self.myUserInfo = userInfo;
}
and add this, which will be called after Cordova is loaded -
- (void)cordovaDidLoad {
//Check that myUserInfo isn't null, that will mean that the app was completely closed and it was opened from the push notification
if (self.myUserInfo) {
NSString* Value1 = [self.myUserInfo objectForKey:@"val1"];
NSString* Value2 = [self.myUserInfo objectForKey:@"val2"];
NSString * jsCallBack = [NSString stringWithFormat:@"testfromdelegate('%@','%@')", Value1, Value2];
NSLog(@"%@", jsCallBack);
[self.viewController.webView stringByEvaluatingJavaScriptFromString: jsCallBack];
}
}