Created
February 23, 2012 02:21
-
-
Save swizzlevixen/1889278 to your computer and use it in GitHub Desktop.
Call Objective-C methods from UIWebView, with optional argument
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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment