0

I managed to download some On-Demand Resources into my Cordova App using a custom plugin that I built.

What I need to do now is load them inside an iframe in my App. Is this possible??

If they were located in the (sigh, read-only) www folder I could simply point to ${cordova.file.applicationDirectory}/www/game.html
...but being them in the Library folder (eg. see path below) is there a way to display them inside an iframe?
('/var/mobile/Library/OnDemandResources/AssetPacks/2F2887A0-7B16-4S5D-83C2-1C588A69DA80/15533301173473852725/com.us-company.sports-beta-enterprise.asset-pack-5a105e8b9d10e3329780d62ea2265d8a.assetpack/game.html')


The only way I managed to display them so far is:

1. InAppBrowser using a cdvfile://localhost path (see below) --> but I would like to avoid this
(cdvfile://localhost/root/Users/user/Library/Developer/CoreSimulator/Devices/D016D3BC-E9F9-43F2-8EC1-9A471819A9B5/data/Library/OnDemandResources/AssetPacks/11129225-E96A-4BEC-9051-735912378DB0/15538308173473832725/com.us-company-us.sports-beta-enterprise.asset-pack-5a105e8b9d40e1329780d62ea2265d8a.assetpack/flying-block-game.html)

2. Parsing the html text myself using document.createRange + createContextualFragment --> becomes complex to manage for non-trivial games.

Any help displaying this inside an iframe in the App itself so that all requests go through the Ionic engine and have my own iosapp:// custom scheme instead of cdvfile://localhost (that will likely result in CORS blockers)?

In alternative, would it work using a different plugin for a local webserver that serves those ODR downloaded files?

                                                                                                Github issue

Gabe
  • 5,997
  • 5
  • 46
  • 92

3 Answers3

2

I easily fixed my problem using cordova-plugin-ionic-webview's window.Ionic.WebView.convertFileSrc:

The game loads correctly inside an iframe in my Cordova App in this way:

var iframe = document.createElement('iframe');
iframe.src = window.Ionic.WebView.convertFileSrc('file:////Users/gsacchi/Library/Developer/CoreSimulator/Devices/D016D2BC-E9F9-43F2-8EC1-9A471819A9B5/data/Library/OnDemandResources/AssetPacks/11159225-E96A-4BEC-9051-735912378DB0/15538308173473832725/com.company-us.sports-beta-enterprise.asset-pack-5a105e8b9d40e2329780d62ea2265d8a.assetpack/flying-block-game.html');
var target = document.body.appendChild(iframe);

Regarding CORS issues, third parties usually don't whitelist file:/// or localhost, the good news though is that: the requests going out from the iframe have the same custom hostname and scheme as the App so there are no CORS issues!

Gabe
  • 5,997
  • 5
  • 46
  • 92
  • This is very interesting. My app hosts files on a my server for users to download and have been using `cordova-plugin-file-transfer/cordova-plugin-file-downloader` to download to users phone with....but they are no longer maintained and breaking in Cordova 11. I need another solution and am considering an iFrame or InAppBrowser in an iFrame solution. I have been using InAppBrowser as a back up and it works, but its an ugly backup. I want to load InAppBrowser in an iFrame, listing files on the server, as if they were listed items in a DIV, I wonder if your solution would work. – rolinger Feb 28 '23 at 20:21
1

If you have the html content already, you can set the iframe content this way, rather than src="...", and you should be able to avoid the CORS issues in WkWebView:

var htmlToWrite = "<html><head></head>" +
    "<body>" +
        "iframe body" +
        "<script>window.parent.alert('iframe even same-origin as parent.');</script>" +
    "</body></html>";
var frameEl = document.createElement('iframe');
frameEl.src = "about:blank";
document.body.appendChild(frameEl);
frameEl.contentWindow.document.open('text/htmlreplace');
frameEl.contentWindow.document.write(htmlToWrite);
frameEl.contentWindow.document.close();

More context: https://stackoverflow.com/a/65132249/5669636

0

I wonder who enforces the www constraint, maybe it's something I can fork and change.. In that case i would be able to load the single games inside an iframe embedded in the ionic-webview served App and more easily address CORS issue since I can rely on my custom scheme and App domain set as preference in the config.xml.

This is the plugin code:

-(NSString *) getStartPath {
    NSString * wwwPath = [[NSBundle mainBundle] pathForResource:@"www" ofType: nil];
    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    NSString * persistedPath = [userDefaults objectForKey:CDV_SERVER_PATH];
    if (![self isDeployDisabled] && ![self isNewBinary] && persistedPath && ![persistedPath isEqualToString:@""]) {
        NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString * cordovaDataDirectory = [libPath stringByAppendingPathComponent:@"NoCloud"];
        NSString * snapshots = [cordovaDataDirectory stringByAppendingPathComponent:@"ionic_built_snapshots"];
        wwwPath = [snapshots stringByAppendingPathComponent:[persistedPath lastPathComponent]];
    }
    self.basePath = wwwPath;
    return wwwPath;
}

..so I would assume something like this should work pointing to the downloaded games ODR folder:

NSString *odrPath= [[NSBundle mainBundle] pathForResource:@"games" ofType: nil];

Not sure whether it would be feasible to have both instances running at the same time though..

More discussion points in the Cordova slack channel: https://cordova.slack.com/archives/C068CHRJ5/p1586747888233400

Gabe
  • 5,997
  • 5
  • 46
  • 92