【swift】WKWebViewでWebViewからネイティブへデータを受け取る方法

もくじ

どうもこんにちは。iOSをメインに開発しているロッキーカナイです。

WebViewを使ったアプリを開発していると、WebView側からデータを受け取りたい場面が出てきます。
今回行うのはWeb上のボタンをクリックしたら、ネイティブでデータを受け取る方法を紹介したいと思います。

環境について

Xcode 9.3

Mac 10.13.4

ローカル環境 MAMP 4.1.1

実装の紹介

はじめに

WebViewで表示させるサイトが必要になるので、MAMPを使ったローカル環境を使用しhtmlへアクセスし表示させます。

サーバ上にhtmlファイルを配置できる方は無視しちゃってね。

Xcodeでの作業

適当にプロジェクトを新規作成しましょう。

次に今回ローカル環境へのアクセスをするのでInfo.plistにApp Transport Security Settings / Allow Arbitrary Loads = YESの設定を追加します。

httpでリクエストを送るとiOS9よりhttpsに置き換わる仕様の為、httpでもリクエストを行えるように設定しました。

次にViewController側のコーディングです。

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // javascriptを呼び出しを可能にするWKUserContentControllerクラスの生成
        let userController = WKUserContentController()
        userController.add(self, name: "callbackHandler")
        
        // WKWebViewの設定を行う為のWKWebViewConfigurationクラスの生成
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.userContentController = userController
        
        // WKWebView生成
        webView = WKWebView(frame: CGRect(x: 0,
                                          y: 0,
                                      width: self.view.frame.size.width,
                                     height: self.view.frame.size.height),
                    configuration: webConfiguration)
        webView.navigationDelegate = self
        webView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(webView)
        
        // 表示するアドレス設定
        let request = URLRequest(url: URL(string: "http://localhost:8888")!)
        self.webView.load(request)
    }

    // WKScriptMessageHandlerプロトコル
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

        if(message.name == "callbackHandler") {
            print(message.body)
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

WebKitのインポートを忘れずに!

viewDidLoadメソッド内で、WKWebViewの生成と設定を行っており、ローカル環境のhttp://localhost:8888を表示します。(サーバ上にhtmlファイルを配置する方は、該当アドレスに変更してください)

Webの作業

次にhtml側のコーディングです。

<html>
  <head>
    <meta charset="utf-8">
    <title>テスト</title>
  </head>
  <body>
    <script>
      function OnButtonClick() {
          window.webkit.messageHandlers.callbackHandler.postMessage("webViewから呼び出し");
      }
    </script>

    <input type="button" value="Webからネイティブにメッセージ送信" onclick="OnButtonClick();" style="width:80%;height:100px;margin:10%;font-size:36px;">
  </body>
</html>

webViewにボタンを用意しクリックするとOnButtonClickがコールされwindow.webkit.messageHandlers.callbackHandler.
postMessage(“webViewから呼び出し”);が実行されます。

これをネイティブのfunc userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)で受け取ります。

実装確認

XcodeをRunすると、シュミレータで以下のように表示されます。

このボタンをクリックすると。

ログが出力されました。

問題なくWebView側からデータを受け取る事が出来ました!!

最後に

現在行っている開発業務で、WebViewからデータを受け取る実装が必要になりましたので、調べた結果を今回まとめてみました。

今回は文字データの取得ですが、実際にはJSONデータなどを使われると思いますので、次回もしかしたら、JSONデータを取得する方法をご紹介するかもしれません。しないかもしれません。

ではでは、よいSwiftライフをお楽しみください〜

関連する記事

  • 映画公開予定通知botを作ってみた!

  • 【Flutter】通信ライブラリRetrofit(Dio)がいい感じ

  • 【Flutter】Riverpod+StateNotifier+freezedで作ろう

  • ChatGPTくんと仲良くなって手羽元の甘辛煮を作るまで

もっと見る