Traveling Tech Guy
Traveling Tech Guy

Reputation: 27849

How to handle a custom URL in an already-open app?


I have an app based on the Utility template (i.e. Main and Flip view controllers). The Flip view allows selecting a certain item to be used on the main view. So far - works great.

Now I tried adding a custom URL. Something to the effect of: myapp://itemID=40 that will basically tell the main view: "no need to flip - you'll be dealing with item 40".

I registered the URL type scheme as "myapp" and added the following method to the app delegate:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    if (!url) {  
        return NO; 
    }

    NSString *urlString = [url absoluteString];
    NSLog(@"URL received: %@", urlString);
    NSString *itemID = [urlString stringByReplacingOccurrencesOfString:@"myapp://itemID=" withString:@""];
    NSLog(@"Item received: %@", itemID);
    [_mainViewController setStartupItem:itemID]; 
    return YES;
}

As you can see, the itemID is set to a property called startupItem in the mainViewController.

I then added one line to the regular application method to verify that startupItem will be nil in case of no URL:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Make sure URL string is empty
    [_mainViewController setStartupItem:nil];

    // Override point for customization after application launch.
    // Add the main view controller's view to the window and display.
    self.window.rootViewController = self.mainViewController;
    [self.window makeKeyAndVisible];
    return YES;
}

And in MainViewController.m I added code to handle the item to the viewDidLoad event.

And here's my problem: this scheme works great if the app is started from a URL the first time. If it's already running, then we never reach viewDidLoad again and therefore don't handle that particular item, but go on as if none was passed.

My humble question is: which UIViewController should I put my handling code in? Or, am I approaching all this the wrong way? Should this be handled in my model?

As always, thanks in advance for your time!

Guy

Upvotes: 0

Views: 2476

Answers (2)

mtwagner
mtwagner

Reputation: 466

I would take a look at the docs for UIApplicationDelegate protocol, specifically;

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

And this which is deprecated.

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

Upvotes: 3

Tomasz Stanczak
Tomasz Stanczak

Reputation: 13164

Well definitely not in a method that gets called only once while the application starts up! You need to refactor the item handling code in its own method, then call this method from viewDidLoad (once during startup) and handleOpenURL each time it gets called.

Upvotes: 1

Related Questions