apache / cordova-ios

Apache Cordova iOS
https://cordova.apache.org/
Apache License 2.0
2.16k stars 985 forks source link

Cannot use custom URL scheme in embedded Web view #1223

Open alekop opened 2 years ago

alekop commented 2 years ago

cordova-ios 6.2.0

I followed the instructions at (https://cordova.apache.org/docs/en/11.x/guide/platforms/ios/webview.html) on embedding a Cordova Web view into a Swift project. I used Carthage, and added the xcframework to my project. It all works, but with the default file protocol. I need the secure context, though, so I tried adding a custom scheme to the config.xml:

<widget id="com.example.test" ios-CFBundleVersion="100" version="1.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <feature name="HandleOpenUrl">
        <param name="ios-package" value="CDVHandleOpenURL" onload="true" />
    </feature>
    <preference name="scheme" value="app" />
    <preference name="hostname" value="localhost" />
</widget>

This results in a blank screen, with about:blank as the location.

My view controller doesn't do anything special, it just inherits CDVViewController.

class CordovaWebViewController: CDVViewController {
}

So I stepped through the CDVWebViewEngine code, and found that the URL being loaded is app://localhost/index.html. So far so good, but we never actually load that URL. Eventually we get to CDVWebViewEngine.decidePolicyForNavigationAction, which ultimately sends a CDVPluginHandleOpenURLNotification. This is handled by the CDVHandleOpenURL plugin, which wasn't being loaded automatically. This was suspicious - am I on the wrong track?

Anyway, I added it to the config.xml manually, and added some NSLogs to that plugin to make sure it loads. The logs revealed that the plugin's applicationLaunchedWithUrl is being called (with the correct URL), but it does nothing because self.pageLoaded is NO. At this point I'm a bit lost, because I don't understand how we expect the page to be loaded when we're in the process of loading it.

Any help would be appreciated. Thanks.

msmtamburro commented 1 year ago

I see a bug here: https://github.com/apache/cordova-ios/blob/master/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m#L343C102-L343C110

The stringWithFormat should be combining two strings, but it is instead combining an NSString and an NSUrl. Adding .absoluteString to the startURL should address this (it's very difficult for me to raise a PR at work, otherwise I'd do this.)

Change: url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", self.CDV_ASSETS_URL, startURL]];

To: url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", self.CDV_ASSETS_URL, startURL.absoluteString]];

Note: without this, loading images off disk will be broken in newer versions of iOS, which I see others reporting in other issues.