How to dynamically change the openURL implementation in my app?

纵然是瞬间 提交于 2019-12-06 13:24:45

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).

You can set the original implementation to some other method and then just call it:

@implementation UIApplication (Private)
- (BOOL)originalOpenURL:(NSURL*)url 
{
     return NO;
}

- (BOOL)customOpenURL:(NSURL*)url
{
     if (/* some condition */)
     {
        // your code
     }
     else
     {
        return [self originalOpenURL: url];
     }
}

@end

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

     method_exchangeImplementations(openUrl, originalOpenUrl); 
     method_exchangeImplementations(openUrl, customOpenUrl);  
}

Note: This is just a solution giving direct answer to your question. The clearer approach to this problem is the one suggested by @edc1591. You can access original openURL: with [super openURL:url].

The approach pointed out by Krizz works on the first app launch only, if you happen to open an URL that redirects you to another App (i.e.: Facebook app), it messes with the implementations when your app is resumed. Adding a flag to make sure the method_exchangeImplementations is called only on the first app launch seems to work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!