Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I handle a Custom URL Scheme in PhoneGap for a cold start?

Tags:

cordova

I'm using handleOpenURL() for a Custom URL Scheme to launch my app from a link in an email. Works perfectly and I can do stuff in my app based on the URL parameters in the link.

The problem is handleOpenURL() doesn't seem to get call when my app does a cold start (not running in the background). Is there another handler that I can use for a cold start vs an already running instance?

OR

Is there a global variable that I can read that will tell me what the invoke URL was? I read about invokeString, but it never seems to be set?

I'm using PhoneGap 2.0

like image 876
SomethingOn Avatar asked Sep 20 '12 14:09

SomethingOn


2 Answers

if you read carefully the comment above the application:handleOpenURL method, you will probably understand:

// this happens while we are running ( in the background, or from within our own app )
// only valid if Calinda-Info.plist specifies a protocol to handle
- (BOOL) application:(UIApplication*)application handleOpenURL:(NSURL*)url

This methods will not be called if the application is not running. My solution was to tweak project with the following changes:

MainViewController.h

@interface MainViewController : CDVViewController
@property (nonatomic, retain) NSString *URLToHandle;
@end

MainViewController.m

- (void) webViewDidFinishLoad:(UIWebView*) theWebView 
{
     if (self.URLToHandle)
     {         
         NSString* jsString = [NSString stringWithFormat:@"window.setTimeout(function() {handleOpenURL(\"%@\"); },1);", self.URLToHandle];
         [theWebView stringByEvaluatingJavaScriptFromString:jsString];
     }
     [...]
}

- (void)dealloc
{
    self.URLToHandle = nil;
    [super dealloc];
}

@synthesize URLToHandle;

AppDelegate.m

- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{   
    [...]
    self.viewController = [[[MainViewController alloc] init] autorelease];
    self.viewController.useSplashScreen = YES;
    self.viewController.wwwFolderName = @"www";
    self.viewController.startPage = @"index.html";
    self.viewController.view.frame = viewBounds;

    // Patch for handleOpenURL
    ((MainViewController *)self.viewController).URLToHandle = URLToHandle;

    [...]
}

Hope that helps.

Cyril

Additional note: when testing make sure you stop xcode. When xcode was running application would throw an exception. if I stop the xcode this solution works fine.

like image 62
cyrilPA Avatar answered Oct 21 '22 10:10

cyrilPA


By the way if anybody runs into this, The only thing missing is defining URLToHandle in AppDelegate (.h and .m) the same way it's been defined in MainViewController.

And also you have to reverse the assignment in AppDelegate.m from:

((MainViewController *)self.viewController).URLToHandle = URLToHandle;

to:

NSString* jsString = [NSString stringWithFormat:@"window.setTimeout(function() {handleOpenURL(\"%@\"); },1);", url];
((MainViewController *)self.viewController).URLToHandle = jsString;

you essentially have to transfer the url from AppDelegate to MainViewController.

setTimeout is critical otherwise it does not work.

like image 45
P Moses Avatar answered Oct 21 '22 10:10

P Moses