LoginSignup
3
3

More than 3 years have passed since last update.

Swiftで取得した画像をWKWebView内のHTMLで表示する方法

Posted at

WkWebviewのコンテンツ内でSwiftで取得したPNG画像などのデータを使いたいケースがあると思います。

本記事ではWebViewJavascriptBridgeを使用した、PNG画像のSwiftとJavaScript間での通信にて表示する方法について記載します。

ローカルのHTMLをWebViewで読み込み(Swift)

まずはWKWebviewでローカルのhtmlを読み込む。

Swift
class ViewController: UIViewController {
    var webView:WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()
        // WKWebViewのViewへの追加
        self.webView = WKWebView(frame: view.frame)
        view.addSubview(self.webView!)
        let htmlPath = Bundle.main.path(forResource: "content", ofType: "html")
        let baseURL = URL.init(fileURLWithPath: htmlPath!)
        webView!.loadFileURL(baseURL, allowingReadAccessTo: baseURL)
    }
}

JavaScriptへのbridge(Swift)

WebViewJavascriptBridgeの初期化と、
registerHandlerにてJavaScript→Swiftへアクセスする受け口作成。

Swift
        self.bridge = WebViewJavascriptBridge.init(forWebView: webView)
        // WKWebView内のjavascriptからSwift内のデータを取得
        self.bridge!.registerHandler("image") { (data, callback) in
        }

JavaScript側のbridge設定(JavaScript)

読み込むhtml内のJavaScriptにてWebViewJavascriptBridgeでSwift間通信するためのテンプレートを追加後、
bridge.callHandlerにてSwift側への画像取得要求を行う。
※詳細はWebViewJavascriptBridge参照

JavaScript
        function setupWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
            if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
            window.WVJBCallbacks = [callback];
            var WVJBIframe = document.createElement('iframe');
            WVJBIframe.style.display = 'none';
            WVJBIframe.src = 'https://__bridge_loaded__';
            document.documentElement.appendChild(WVJBIframe);
            setTimeout(function () { document.documentElement.removeChild(WVJBIframe) }, 0)
        }

        setupWebViewJavascriptBridge(function (bridge) {
            bridge.callHandler('image', { 'key': 'value' }, function responseCallback(responseData) {
            })
        })

Base64データへの変換(Swift)

WKWebview側でPNGを読み込むためbase64のstringへ変換してJavaScript側へ返却。

Swift
        self.bridge!.registerHandler("image") { (data, callback) in
            if let imagePath = Bundle.main.path(forResource: "PNG", ofType: "png") {
                // PNGをUIImageに
                let image = UIImage(contentsOfFile: imagePath)
                // Data型へ変換
                let data = image?.pngData()
                // PNGのデータをbase64エンコードしてWebViewで表示できるよう修正
                let base64Image = data?.base64EncodedString(options: .endLineWithLineFeed)
                callback!(base64Image)
            }
        }

base64形式のPNGデータの読み込み

Swift側から返却されたbase64形式のresponseDataは、
PNGのデータURIとなっていないため、先頭に
data:image/png;base64,
を追加してimgタグで読み込み。

JavaScript
            bridge.callHandler('image', { 'key': 'value' }, function responseCallback(responseData) {
                var html = [
                ];
                html += '<img src="data:image/png;base64,'
                html += responseData
                html += '" alt="PNG"/>'
                document.getElementById("content").innerHTML = html
            })

上記にてWKWebview上でSwiftで取得したPNGが表示される。

サンプルアプリ

GitHubにて上記ソースのサンプルアプリ公開しています。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3