3

I'm very new to Cordova, so it may be that I don't fully understand its purpose. Let me start with what I'm trying to achieve overall.

We have an asp.net website that has mobile support, that I'm basically just trying to wrap with an iPhone app. The site of course runs on an IIS server, so I just want a thin wrapper to launch the site, and remove the address bar, navigation, etc. It's my understanding that you can achieve that with the Cordova hybrid approach.

I followed the tutorial, and got the site to launch within an xCode iPhone Simulator, and it came up just like I wanted to.

The problem I'm having is that hyperlinks within the site launch the target page in a Safari browser. And from all of my googling, it seems like this is the opposite problem most people have. It seems like most people struggle with external sites opening within the app, which basically locks them out of their app. I'm just trying to go from Page1 to Page2 on my own site within the app.

I was able to reproduce this problem with the simplest of sites, so I'll post the relevant bits. In this example, clicking on "Page 2" will open up in Safari.

Asp.net site:

Page1.html

<html>
    <a href="page2.html">Page 2</a>
</html>

Page2.html

<html>
    Page 2
</html>

Cordova:

Index.html

<!DOCTYPE html>
<html>
    <head>
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    </head>
    <body>
        Cordova site
    </body>
    <script>
        window.location = "http://192.168.1.157:8081/Page1.html";
    </script>
</html>

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="vsisolutions.testsite" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>Test Site</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <allow-navigation href="http://192.168.1.157:8081/*" />
    <allow-navigation href="*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
    <engine name="ios" spec="~4.1.1" />
    <plugin name="com.msopentech.authdialog" spec="~0.1.6" />
</widget>

Thanks for the help!

Brian
  • 325
  • 2
  • 10
  • It happens because when the webview decides what to do with the url it looks for any plugins that can help. It looks like one is responding. I'm looking into this in more detail now. – Guy Lowe Jun 16 '16 at 23:49
  • I just found this possible dupe which has the same solution to mine: http://stackoverflow.com/questions/36572869/why-are-links-inside-an-iframe-opening-in-system-safari – Guy Lowe Jun 17 '16 at 02:24

4 Answers4

2

I found that in Cordova the WKWebView plugin (it could be occurring in the UIWebView as well) asks around for any other plugins to see if they can use URL on the link. This was being picked up by the CDVIntentAndNavigationFilter and running through the logic as in:

- (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:    (UIWebViewNavigationType)navigationType
{
   NSURL* url = [request URL];

 switch (navigationType) {
    case UIWebViewNavigationTypeLinkClicked:
        // Note that the rejection strings will *only* print if
        // it's a link click (and url is not whitelisted by <allow-*>)
        if ([self.allowIntentsWhitelist URLIsAllowed:url]) {
            // the url *is* in a <allow-intent> tag, push to the system
            [[UIApplication sharedApplication] openURL:url];
            return NO;
        }
        // fall through, to check whether you can load this in the webview
    default:
        // check whether we can internally navigate to this url
        return ([self.allowNavigationsWhitelist URLIsAllowed:url]);
    }
}

Because the navigationType == UIWebViewNavigationTypeLinkClicked it was passing it off to the browser via [[UIApplication sharedApplication] openURL:url];

Currently I have only found a hack around this and that is to override this logic by treating links in the same way i.e. like so:

switch (navigationType) {
  case UIWebViewNavigationTypeLinkClicked:
    // Note that the rejection strings will *only* print if
    // it's a link click (and url is not whitelisted by <allow-*>)
    if ([self.allowIntentsWhitelist URLIsAllowed:url]) {
        // the url *is* in a <allow-intent> tag, push to the system
       // [[UIApplication sharedApplication] openURL:url];
        return YES;
    }
    // fall through, to check whether you can load this in the webview
  default:
    // check whether we can internally navigate to this url
    return ([self.allowNavigationsWhitelist URLIsAllowed:url]);
    }
}

This is obviously not ideal and I'll ask around on the Cordova forum for a better solution which I'll post here once I find it.

Guy Lowe
  • 2,115
  • 1
  • 27
  • 37
2

This was a bug

It was fixed on latest released version of cordova-ios 4.2.0

So you don't have to do any hack to make it work anymore, just have to use the allow-navigation tag to set the urls you want to allow to navigate inside the app, and the rest of them will open in safari as you have allow-intent set for all http and https urls.

jcesarmobile
  • 51,328
  • 11
  • 132
  • 176
  • Thank you! I didn't fully understand intent vs navigation until I read this, this cleared a lot up and got my links working correctly (so far at least). – Jake Oct 30 '16 at 21:50
0
<a href="page2.html" target="_blank">Page 2</a>

This should work.

May Rest in Peace
  • 2,070
  • 2
  • 20
  • 34
  • Tried adding target="_blank" but that didn't do it. "_blank" would make it more likely to open in the browser, wouldn't it? Also tried _self, but that didn't seem to make any difference either. – Brian Jun 16 '16 at 20:16
0

Just changing allow-navigation to append with * worked:

<allow-navigation href="http://yourwebsite/*" />
double-beep
  • 5,031
  • 17
  • 33
  • 41