imgcache.js icon indicating copy to clipboard operation
imgcache.js copied to clipboard

Unsupported URL issue on WKWebView

Open manishoswal opened this issue 7 years ago • 17 comments

The image caching works fine on ios app (cross platform) if we do not use cordova-plugin-ionic-webview as soon as we install this plugin i am getting the following error

Error - Failed to load resource: unsupported URL cdvfile://localhost/persistent/imgcache/adf3c56ed32d0fc3206e4adff2b608bad41aff38.png

manishoswal avatar Sep 28 '17 12:09 manishoswal

Hi,

so I assume that you are using the ionic wkwebview plugin. If thats the case here is a workaround for the problem:

You need to install the cordova file plugin first.

ImgCache.getCachedFileURL(src,
            (originalUrl, cacheUrl) => {
              const file = new File();
              const cacheFileUrl = cacheUrl.replace('cdvfile://localhost/persistent/', file.documentsDirectory);
              const localServerFileUrl = cacheFileUrl.replace('file://', 'http://localhost:8080');
              //localServerFileUrl contains the loadable url
              resolve(localServerFileUrl);
            },
            (e) => {
              console.error('img-cache-error:', e);
              reject(e)
            });

Hope this fix your problem.

gkTim avatar Sep 29 '17 07:09 gkTim

I am facing th same issue, the solution suggested above is not working for me.

ish3lan avatar Oct 01 '17 05:10 ish3lan

Its not working for me when i use iosPersistentFileLocation as Library. Getting 404 error. You need to change iosPersistentFileLocation to Compatibility for the above solution to work.

manishoswal avatar Oct 03 '17 10:10 manishoswal

@manishoswal can you please give an example about it? Apparently it is not possible to use cdvfile with WKWebView. Regards!

owen2345 avatar Nov 22 '17 13:11 owen2345

@owen2345 - You need to implement the changes suggested by gkTim on Sep 29 and also update the config.xml file to

manishoswal avatar Nov 22 '17 14:11 manishoswal

hey guys, I've fixed the problem. Here you can find an example https://github.com/mahcr/offline-ionic

marianocodes avatar Feb 11 '18 05:02 marianocodes

@mahcr did you manage to have it working without @Maistho 's pull request? I'm considering whether this PR is required or not for Ionic.

chrisben avatar May 06 '18 07:05 chrisben

It is not required do this conversion inside imgcache.js, but it is required to add code to edit the url that is received from imgcache.js otherwise.

Maistho avatar May 06 '18 09:05 Maistho

#228

Cntryboy82 avatar Oct 28 '18 12:10 Cntryboy82

Any updates on this? Mistho's PR does not work for me, window.Ionic.normalizeURL doesn't change the url of type cdvfile//..., so the resulting url is still incompatible.

jperez1111 avatar Mar 13 '19 07:03 jperez1111

To get a loadable url for both iOS and Android, I came up with the following solution, based on cordova-plugin-file documentation:

window.resolveLocalFileSystemURL(cacheUrl, (entry: any) => {
   cacheUrl = entry.toURL();
   const ionicNormalizer = window.Ionic &&
      ((window.Ionic.WebView && window.Ionic.WebView.convertFileSrc) || window.Ionic.normalizeURL);
   if (typeof ionicNormalizer === "function") {
       cacheUrl = ionicNormalizer(cacheUrl);
   }

entry.toURL() will convert cdvfile:// url to a native path, i.e. an absolute file:// url. The ionicNormalizer will then normalize this url, e.g. to a localhost url.

jperez1111 avatar Mar 24 '19 02:03 jperez1111

Sweet victory @jperez1111 you are the bomb!!!

bocodigital avatar Apr 16 '19 18:04 bocodigital

Fixed the problem using @jperez1111's reply and with some changes as mentioned in https://github.com/chrisben/imgcache.js/issues/237#issuecomment-496185249

AhsanAyaz avatar May 27 '19 11:05 AhsanAyaz

Here is what I did to fix loading of images cached with ImgCache.js under WKWebView.

  1. Add this line to config.xml:
    <platform name="ios">
        <!-- Line here under iOS settings -->
        <preference name="iosPersistentFileLocation" value="Library" />
  1. Use next code to normalize URL loaded from ImgCache.js:
    private normalizeUrl(url: string) {
        let result = url;

        const cdvfilePrefix = 'cdvfile://localhost/persistent/imgcache/';
        if (ionic.Platform.isIOS() && url.indexOf(cdvfilePrefix) === 0 ) {
            result = this.getIosImgCacheDirectoryUrl() + url.split(cdvfilePrefix)[1]
        }

        if (ionic.Platform.isIOS()) {
            result = result.replace(/^file:\/\//g, '');
        }

        return result;
    }

    private getIosImgCacheDirectoryUrl(): string {
        return cordova.file.dataDirectory.split('Library')[0] + 'Library/files/imgcache/';
    }
  1. After that use it on the cachedUrl
      ImgCache.getCachedFileURL(src,
            (originalUrl, cacheUrl) => {
              const localUrl = this.normalizeUrl(cacheUrl);
              // now you can use it for <img src="{{localUrl}}>
            });

The resulting URL on iOS will be something like:

/var/mobile/Containers/Data/Application/<UUID>/Library/files/imgcache/<UNIQUE_FILE_ID>

Note that it must start with /, not with cdvfile://, nor file://, nor http://localhost:8080/, nor anything else

afrish avatar Nov 15 '19 13:11 afrish

@jperez1111 awesome! Anything we have to do differently or modify if not using Ionic, to get this to work?

tryhardest avatar Feb 05 '20 20:02 tryhardest

@tryhardest sorry, I haven't used this library in any other context than with Ionic.

jperez1111 avatar Feb 05 '20 20:02 jperez1111

To get a loadable url for both iOS and Android, I came up with the following solution, based on cordova-plugin-file documentation:

window.resolveLocalFileSystemURL(cacheUrl, (entry: any) => {
   cacheUrl = entry.toURL();
   const ionicNormalizer = window.Ionic &&
      ((window.Ionic.WebView && window.Ionic.WebView.convertFileSrc) || window.Ionic.normalizeURL);
   if (typeof ionicNormalizer === "function") {
       cacheUrl = ionicNormalizer(cacheUrl);
   }

entry.toURL() will convert cdvfile:// url to a native path, i.e. an absolute file:// url. The ionicNormalizer will then normalize this url, e.g. to a localhost url.

Thank you so much, this is working for me

maximnara avatar Feb 07 '21 17:02 maximnara