10

I went to use UIWebView to display dynamic content, instead of doing it natively using UI-elements. Is it possible to trigger native app functions from simply hitting links inside the UIWebView? Example: hitting a link which then switches current View?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Leonardo DaVintik
  • 555
  • 1
  • 9
  • 18

3 Answers3

24

Yes, it's possible. In your html, you write a JS to load a URL with a fake scheme such as

window.location = "request_for_action://anything/that/is/a/valid/url/can/go/here";

Then, in your iOS code, assign a delegate to your webView, and in your delegate, handle

webView:shouldLoadWithRequest:navigationType

with something like

if( [request.URL.scheme isEqualToString: @"request_for_action"] )
{
   // parse your custom URL to extract parameter, use URL parts or query string as you like
   return NO; // return NO, so webView won't actually try to load this fake request
}

--

Just an aside, you can do the other way, let iOS code invoke some JS codes in your html by using

NSString* returnValue = [self.webView stringByEvaluatingJavaScriptFromString: "someJSFunction()"];
yc.lin
  • 379
  • 1
  • 6
9

Yes! When the user presses a link, you hear about it in the web view's delegate and can then do whatever you want. Powerful stuff can be done this way.

The web view's delegate is sent webView:shouldStartLoadWithRequest:navigationType:. You analyze what happened, and respond as you wish. To prevent the web view from trying to follow the link (which may be completely fake, after all), just return NO.

In this example from the TidBITS News app, I have a link in the Web page that uses a totally made-up play: scheme. I detect that in the delegate and play:

- (BOOL)webView:(UIWebView *)webView
        shouldStartLoadWithRequest:(NSURLRequest *)r
        navigationType:(UIWebViewNavigationType)nt {
    if ([r.URL.scheme isEqualToString: @"play"]) {
        [self doPlay:nil];
        return NO;
    }
    if (nt == UIWebViewNavigationTypeLinkClicked) {
        [[UIApplication sharedApplication] openURL:r.URL];
        return NO;
    }
    return YES;
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • It looks exactly what I need to accomplish. But I can't figure out where do I put this method? Thanks for the descriptive answer, by the way! – Leonardo DaVintik Apr 18 '13 at 04:26
  • You put it wherever is the UIWebView's delegate! – matt Apr 18 '13 at 04:33
  • Alwesome, this works! :) One more question: why is it that when I click the link with predefined url-scheme, the app redirects to Safari and tries to open it? – Leonardo DaVintik Apr 18 '13 at 06:26
  • 1
    Because you didn't read the docs? Because you didn't look at my example? Because you didn't return NO? – matt Apr 18 '13 at 14:32
2

Implement the UIWebViewDelegate method webView:shouldStartLoadWithRequest:navigationType:.

Handle navigationType and the request as needed.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • I have set the delegate and implemented the uiwebview delegate methods. But none of my delegate methods are called when I click on some uiwebview contents. There is no callback. What should be done? – iPhoneDeveloper Jan 08 '18 at 13:20
  • @iPhoneDeveloper You should post your own question with all relevant details. – rmaddy Jan 08 '18 at 16:05