WkWebviewのコンテンツ内でSwiftで取得したPNG画像などのデータを使いたいケースがあると思います。
本記事ではWebViewJavascriptBridgeを使用した、PNG画像のSwiftとJavaScript間での通信にて表示する方法について記載します。
ローカルのHTMLをWebViewで読み込み(Swift)
まずはWKWebviewでローカルのhtmlを読み込む。
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へアクセスする受け口作成。
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参照
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側へ返却。
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タグで読み込み。
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が表示される。