WKWebView環境でダウンロードした画像を表示してみる

Monacaチームの小田川です。

これまでは、Qiitaに月一くらいのペースで投稿していましたが、今回からアシアルブログに投稿することになりました。今回は、WKWebView環境で外部サーバからダウンロードした画像を画面に表示するテストをしてみたいと思います。

サンプルイメージ

file:// スキーム

Monacaで利用しているCordovaでは、外部リソースにアクセスする際に、file:// スキームが使用されます。WKWebViewでは、セキュリティー制限により、file:// スキームでリソースにアクセスすることができません。

Monacaプロジェクトの www フォルダ内に配置されているリソースの場合は、Monacaから提供されている Custom Schemeプラグイン を使用することで対応することができますが、外部サーバからアプリ内にダウンロードした画像ファイルなどには、アクセスすることができません。

ダウンロードした画像を表示する

外部サーバからアプリ内にダウンロードした画像ファイルなどにアクセスする場合は、blob データを利用します。

ダウンロードする画像ファイルをblobデータとしてダウンロードした場合は、window.URL.createObjectURL から取得できるURLを使用することで、画像にアクセスすることができます。

<body>
  <input type="button" value="downloadFile1" onclick="downloadFile1()" />
  <img id="img1" />
</body>

blobデータとして画像を表示するため、Content-Security-Policyblob: を追加する必要があります。

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

WKWebView用のカスタムビルドデバッガーで window.URL.createObjectURL を使用した場合は、下記のようなURLが取得されます。

blob:monaca-debugger://アプリID.monaca.io/99e8aba5-f365-4b3c-b17a-bac2ec802dab

デバッグビルドしたアプリで window.URL.createObjectURL を使用した場合は、下記のようなURLが取得されます。

blob:null/c1212065-cb51-4d73-911b-e1b2e9ccb559

WKWbViewでは、file:// スキームが null に変換されます。

上記のような null が設定されたURLでも画像が表示されますが、Custom Schemeプラグインを有効にした場合は、下記のようなURLが取得されます。

blob:monaca-app://monaca.io/c1212065-cb51-4d73-911b-e1b2e9ccb559

ダウンロードしてファイル保存した画像を表示する その1

ダウンロードしてファイル保存した画像の場合も、保存した画像ファイルをblobデータとして取得することで、window.URL.createObjectURL を利用することができます。

サンプルでは、Fileプラグイン を使用しています。
Fileプラグインの cordova.file.documentsDirectory から取得できるDocumentsフォルダパスにダウンロードしたファイルを保存しています。

<body>
  <input type="button" value="downloadFile2" onclick="downloadFile2()" />
  <img id="img1" />
</body>

画像を表示するためのURLに fileEntry.toURL() を使用した場合は、file:// スキームパスになるため、画像は表示されません。

インスペクターで確認すると、下記のようなエラーが表示されます。

Not allowed to load local resource: file:///var/mobile/Containers/Data/Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents/sample.png
Failed to load resource: The operation couldn’t be completed. Operation not permitted

ダウンロードしてファイル保存した画像を表示する その2

WKWebViewの file:// スキーム制限は、ファイルが保存されている場所に依存しています。

ダウンロードしてファイル保存した画像を表示する その1 では、ファイルの保存場所に cordova.file.documentsDirectory を指定しました。この cordova.file.documentsDirectory で取得できるパスは、アプリ内の Documents フォルダになります。Documentsフォルダの場合は、file:// スキーム制限が適用されます。

アプリ内の tmp フォルダ内のファイルの場合は、file:// スキーム制限は適用されません。そのため、tmpフォルダ内のファイルの場合は、file:// スキームのパスを使用することができます。tmpフォルダのパスは、cordova.file.tempDirectory で取得できます。

注意点として、Custom Schemeプラグインを有効にしている場合や、WKWebView用のカスタムビルドデバッガーを使用している場合は、仕様上、file:// スキーム制限が適用されるため、window.URL.createObjectURL を使用してください。

おわりに

WKWebView環境でダウンロードした画像などが表示されない場合は、一度、window.URL.createObjectURL で取得したURLやファイルの保存先を cordova.file.tempDirectory にして試してみてください。