Search code examples
iphoneobjective-cxcodeopenurl

How to dynamically change the openURL implementation in my app?


In my app, I have implemented a private method in my AppDelegate to override the default openURL: method in order to open links inside my app within UIWebView. But now I need the default functionalities in place too.

Here's what I did:

@implementation UIApplication (Private)

- (BOOL)customOpenURL:(NSURL*)url
{ 
    AppDelegate *MyWatcher = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    if (MyWatcher.currentViewController) {
        [MyWatcher.currentViewController handleURL:url];
        return YES;
    }
    return NO;
}

@end

- (void)applicationDidBecomeActive:(UIApplication *)application {  
    Method customOpenUrl = class_getInstanceMethod([UIApplication class], @selector(customOpenURL:));
    Method openUrl = class_getInstanceMethod([UIApplication class], @selector(openURL:));

   method_exchangeImplementations(openUrl, customOpenUrl);  
}

I also implemented handleURL: in my class where the custom open URL handling was needed. However, this is hindering my other class in which I just want to do a simple open of an iTunes link in iTunes. So what I don't know how to achieve is how to use the original openURL: in place of customOpenURL:.


Solution

  • You can just subclass UIApplication and override openURL: directly. Be sure to change the principle class in your Info.plist to use your UIApplication subclass.

    Example:

    @interface ECApplication : UIApplication
    
    @end
    
    @implementation ECApplication
    
    - (BOOL)openURL:(NSURL*)url
    {
    
        AppDelegate *MyWatcher = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    
        if (MyWatcher.currentViewController) {
            [MyWatcher.currentViewController handleURL:url];
            return YES;
        }
        return NO;
    }
    
    @end
    

    Then, in your Info.plist file, look for the Principle Class key, and change the value to ECApplication (or whatever you name your subclass).