Reputation: 5742
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:
.
Upvotes: 2
Views: 3786
Reputation: 33
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.
Upvotes: 0
Reputation: 11552
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]
.
Upvotes: 2
Reputation: 10182
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).
Upvotes: 4