This post was published more than a few years ago (on 2012-02-23) and may contain inaccurate technical information, outmoded thoughts, or cringe takes. Proceed at your own risk.
Here’s my solution:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// by Mark Boszko | |
// | |
// Expanded from code by DAMIEN LE BERRIGAUD | |
// http://meliondesign.blogspot.com/2010/02/mapping-uiwebview-links-to.html | |
// | |
// | |
// Sample code to return a method call, | |
// with or without argument, from UIWebView | |
// links with format: | |
// selector://selectorString#argument [#argument is optional] | |
// | |
// This would go in your controller/delegate file. | |
// | |
// for instance: | |
// | |
// selector://linkIntercept | |
// will call | |
// - linkIntercept | |
// | |
// selector://linkInterceptWithArgument#arg | |
// will call | |
// - linkInterceptWithArgument:arg | |
// | |
// You might want to change the selector:// scheme to | |
// something with random characters, like qa7cf3xr:// | |
// to avoid overriding another app's registered scheme | |
// on the user's device, and provide minimal protection | |
// against malicious URLs. | |
// In fact, you could generate the random scheme string | |
// at runtime, if you really want to go nuts. | |
// | |
// Mike Ash suggested security improvements | |
// | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
self.webView.delegate = self; | |
NSString *htmlString = @"<!DOCTYPE HTML><html><body><p><a href=\"selector://linkIntercept\">Log me!</a></p><p><a href=\"selector://linkInterceptWithArgument#arg\">Log me with argument!</a></p></body></html>"; | |
[self.webView loadHTMLString:htmlString baseURL:nil]; | |
} | |
#pragma mark - Web view delegate method | |
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { | |
NSLog(@"%@ %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); | |
NSString *scheme, *selectorString, *argumentString = nil; | |
// Intercept the link | |
if (navigationType == UIWebViewNavigationTypeLinkClicked) { | |
[webView stopLoading]; | |
// Grab the parts of the URL we need | |
// <scheme>://<host>#<fragment> | |
scheme = [[request URL] scheme]; | |
selectorString = [[request URL] host]; | |
argumentString = [[request URL] fragment]; | |
// Check for our selector:// scheme, then match it to a method we'll allow (thanks Mike Ash) | |
if ([scheme isEqualToString: @"selector"]) { | |
if ([selectorString isEqual: @"linkIntercept"]) { | |
[self linkIntercept]; | |
} else if ([selectorString isEqual: @"linkInterceptWithArgument"]) { | |
[self linkInterceptWithArgument: argumentString]; | |
} else { | |
NSLog(@"Could not match selector: %@", selectorString); | |
} | |
} | |
return NO; | |
} | |
// Let other links be handled by the webview. | |
return YES; | |
} | |
#pragma mark - methods called from web links | |
- (void)linkIntercept { | |
NSLog(@"%@ %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); | |
} | |
- (void)linkInterceptWithArgument:(NSString *)argument { | |
// insert code here to make sure argument is something valid for your method | |
// and won't cause a crash or load unwanted data (thanks again Mike Ash) | |
NSLog(@"%@ %@ %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), argument); | |
} |