Skip to content

Instantly share code, notes, and snippets.

@swizzlevixen
Created February 23, 2012 02:21
Show Gist options
  • Save swizzlevixen/1889278 to your computer and use it in GitHub Desktop.
Save swizzlevixen/1889278 to your computer and use it in GitHub Desktop.
Call Objective-C methods from UIWebView, with optional argument
//
// 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