Search code examples
javascriptswifttypescriptcordovaweb-worker

Get Cordova plugin file to fully work in a web worker


I'm running an app with Cordova that has an extremely heavy optional file download. When run on the main thread iOS will shut down the app because it is running too long. In order to solve this, I decided to use web workers so it could run on a separate thread, (the error I was getting said to run the process on a separate thread). Since then I've had difficulties getting the plugins to work in a separate worker. Thus far I've been able to load Cordova and its plugin scripts and am able to call the modules but they are failing to call the native code because the native code relies on window.webkit.messageHandlers.cordova. As far as I can tell, when swift exposes the js methods it only exposes it to the main thread and there is no way to access the native code from the worker. Is there any other way to call native code from the worker that I'm missing?

(self as any).window = self;
(self as any).window.document = self;
(self as any).document = self;
(self as any).window.webkit = (window as any).webkit || {
  messageHandlers: {}
};
// import the scripts from their location in the www folder
const pathToCordovaPluginFile = "../plugins/cordova-plugin-file/www/";
importScripts(
  "../cordova.js",
  pathToCordovaPluginFile + "requestFileSystem.js",
  pathToCordovaPluginFile + "FileError.js",
  pathToCordovaPluginFile + "FileSystem.js",
  pathToCordovaPluginFile + "fileSystems.js",
  pathToCordovaPluginFile + "DirectoryEntry.js",
  pathToCordovaPluginFile + "Entry.js",
  pathToCordovaPluginFile + "DirectoryReader.js",
  pathToCordovaPluginFile + "Metadata.js"

  // pathToCordovaPluginFile + "File.js",
  // pathToCordovaPluginFile + "FileEntry.js",
  // pathToCordovaPluginFile + "FileReader.js",
  // pathToCordovaPluginFile + "FileWriter.js",
);

const getFileSystem = (PERSISTENT: number) => {
  try {
    const requestFileSystem: Window["requestFileSystem"] = cordova.require(
      "cordova-plugin-file.requestFileSystem"
    );
    return new Promise<FileSystem>((resolve, reject) =>
      requestFileSystem(PERSISTENT, 0, resolve, reject)
    );
  } catch {
    console.error("unable to request file system");
  }
};

(my code is technically in typescript not javascript)


Solution

  • AFAIK web workers are NOT available on iOS WKWebView for iOS < 14

    More information here and here

    You should consider modifying the plugin to run your download on a sub native thread.