Titanium JIRA Archive
Appcelerator Community (AC)

[AC-6568] iOS: WebView.setHtml with baseURL doesn't seem to work correctly

GitHub Issuen/a
TypeBug
Priorityn/a
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsTitanium SDK & CLI
Labelsn/a
ReporterTeun Klijn
AssigneeAbir Mukherjee
Created2020-07-07T12:40:57.000+0000
Updated2020-07-21T08:01:56.000+0000

Description

*Summary* I'm downloading some images from the internet and storing them in the Ti.Filesystem.applicationDataDirectory. Since WKWebView was introduced we can no longer access the application directory directly, but I thought we could work around this by setting the baseURL in the second parameter of WebView.setHTML. *Step to reproduce*

Add the example code to a Titanium classic project

Set the SDK to 9.0.3.GA

Run the app on iOS and wait for the webview to load (black content)

const window = Ti.UI.createWindow();
const wv = Ti.UI.createWebView();
window.add(wv);

function getContentDir() {
  var dir = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'content/');
  if (!dir.exists()) {
    dir.createDirectory();
  }
  return dir;
}

function getImage() {
  const contentDir = getContentDir();
  return Ti.Filesystem.getFile(contentDir.nativePath, 'image.png');
}

function request() {
  return new Promise(function (resolve, reject) {
    const req = Ti.Network.createHTTPClient({
      onload: () => {
        resolve(req.responseData);
      },
      onerror: (error) => {
        reject(error);
      },
      timeout: 15000
    });

    req.open("GET", "https://www.appcelerator.com/wp-content/uploads/Axway_logo_horiz_clr_rev_rgb.png");
    req.send(null);
  });
}

function getWrappedHTML(bodyContent) {
  return <!doctype html>
          <html>
            <head>
              <meta charset="utf-8">
              <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
            </head>
            <body style="background-color: black;">
              <div>${bodyContent}</div>
            </body>
          </html>;
}

function loadImage() {
  console.log(getContentDir().nativePath);
  // setHtml with baseURL
  wv.setHtml(getWrappedHTML(<img src="image.png" />), { baseURL : getContentDir().nativePath });
}

window.addEventListener('open', () => {
  const image = getImage();

  if (image.exists()) {
    loadImage(image);
  } else {
    request().then((response) => {
      image.write(response);
      loadImage(image);
    }).catch((error) => {
      console.log(error);
    });
  } 
});

window.open();
*Expected result* The webview shows the axway logo on a black background. *Actual result* The webview shows a black background with a missing image.

Comments

  1. Joshua Quick 2020-07-07

    As of 9.0.0, the WebView has a new "assetsDirectory" property. Set it to the same directory as your "baseURL". https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.WebView-property-assetsDirectory This is a security feature in Apple's WKWebView. You have to give it permission to access files from local storage by setting this property.
  2. Teun Klijn 2020-07-08

    Thank you for your feedback, but it still doesn't work when I set the assetsDirectory. This does work when I set the url property instead using setHtml, but I don't want to use html files. The strange thing is that I don't even see the image on a simulator, and I think a simulator does have access to the application directory without setting the assetsDirectory right?
  3. Teun Klijn 2020-07-16

    Is there any update on this?
  4. Vijay Singh 2020-07-20

    [~teunklijn@telfort.nl] See discussion in TIMOB-27064. Probably it will help you. So - 1. It is limitation from WKWebView. 2. Either you can use base64 encoding of image in your html text (example is given in comment section of TIMOB-27064) Or 3. Write your html data in a file and use in combination with assetsDirectory (again example is in comment section of TIMOB-27064) Thanks!
  5. Teun Klijn 2020-07-21

    Ok thanks! I was already using the base64 method, so I guess I'll keep using that.

JSON Source