Search code examples
ioscordovainappbrowser

Cordova InAppBrowser stuck on loading


I'm trying to get the InAppBrowser to display a local file hosted in Cordova Local Webserver on my iOS device . However, it just comes up with a blank page with "Loading..." bar at the bottom.

I've searched around for solutions but they all seem to go back to whitelist and content security policy, which I've already included in my config.xml and index.html, respectively.

config.xml

...
<access origin="*" />
<allow-intent href="*" />
<allow-navigation href="*" />
....

index.html

...
<meta http-equiv="Content-Security-Policy" content="default-src * gap://ready file:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.gstatic.com https://*.googleapis.com;">
...

I try to open the file using

// url is "http://localhost:8080/local-filesystem/Users/<user>/Library/Developer/CoreSimulator/Devices/E22F3966-CA8B-43E4-890B-EB078C437F54/data/Containers/Data/Application/146AFBF3-5CFF-47D1-9D51-85CFC5676761/Documents/NoCloud/Download/00P1J00000UGDF9UAP_test.pdf"
cordova.InAppBrowser.open(url, '_blank', 'location=yes');

The modal opens, but only "Loading..." bar is shown with Done and Navigation buttons. (This is also all after deviceready)

I am able to inspect the instance with Safari as well and it seems like nothing is loaded onto the instance (about:blank).

I have even tried with

cordova.InAppBrowser.open('http://google.com', '_blank', 'location=yes');

And that gets stuck on loading as well.

If I use '_self' instead of '_blank', everything loads, but it takes over my app's Cordova Webview instance, which is not what I want. Using '_system' opens the system browser, but does not allow me to display files from my Cordova Local Webserver.

Can anyone please point me towards the right direction of making my local file or webpage show via modal using InAppBrowser on iOS?

I am using:

Cordova 7.0.1

cordova-plugin-whitelist 1.0.0 "Whitelist"

cordova-plugin-inappbrowser 1.7.1 "InAppBrowser"

Thanks for your help!


Solution

  • After debugging this and looking for answers for over a week, I found solutions to my problem through the documentation and looking through plugin code:

    Firstly, to display ANY webpage, I found the same solution as this user from this question:

    why does inAppBrowser open a blank new webview which i cant close

    + (void)acquireLock:(void (^)(NSInteger lockToken))block
    {
    if (gCurrentLockToken == 0) {
        gCurrentLockToken = ++gNextLockToken;
        VerboseLog(@"Gave lock %d", gCurrentLockToken);
        block(gCurrentLockToken);
    } else {
        if (gPendingSetUserAgentBlocks == nil) {
            gPendingSetUserAgentBlocks = [[NSMutableArray alloc] initWithCapacity:4];
        }
        VerboseLog(@"Waiting for lock");
        [gPendingSetUserAgentBlocks addObject:block];
    }
    }
    

    gCurrentLockToken was already 1 from the app instance, so InAppBrowser never loaded the url. I could not find any preferences for Cordova config.xml to change this flow, but the link above provides a workaround.


    Secondly, to display a file in Cordova Local Web Server, I had to follow the docs:

    https://www.npmjs.com/package/local-webserver

    In order to limit access to your app, requests are restricted to localhost and are protected with an auth token. This should effectively restrict access to the server to your app.

    Documentation for this is not very thorough, but in my Cordova application in iOS, the auth token is passed in as a param into the application's url document.location.search. So my JS comes down to this:

    cordova.InAppBrowser.open(url + document.location.search, '_blank', 'location=yes'); 
    

    I also removed InAppBrowser's pdf check logic from its plugin code to rid of its console outputs, and it works as expected

    cordova-plugin-inappbrowser 1.7.1 "InAppBrowser"