0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WKWebViewのJavaScriptとNativeの連携(使用例付き)

Posted at

WKWebViewのJavaScriptとNativeの連携(使用例付き)

⭐️WKUserScript

概要

  • 任意のJSからWKUserScriptを作成して、WebViewのインスタンス生成前にScript挿入処理を行うことでJSの処理をWebViewに反映できる

使用例

  • 下記コードでは以下2つのJSをexcutableJSScript()で作成して実行しています
    • WebView内ページでメニューボタンを非表示にする
    • WebViewで拡大・縮小しないようにする
    override func viewDidLoad() {
        super.viewDidLoad()

        let controller = WKUserContentController()
        
        // controllerにWKUserScriptを追加
        controller.addUserScript(excutableJSScript())
        
        // WKWebView インスタンス生成時に適用
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = controller

        webView = WKWebView(frame: view.frame, configuration: configuration)
        view.addSubview(webView)
    }
        
      // 任意の WKUserScriptを作成
     private func excutableJSScript() -> WKUserScript {
            
        // メニューアイコン非表示処理のscript
        let disableWebMenuIconScript = "WebView内ページのメニューアイコンを非表示にするJS"
        
        // 拡大・縮小無効処理のscript
        let disableWebViewScalingScript = "拡大・縮小無効にするJS"

       // 2つのScriptを足して1つのScriptにする
        let excutableJSScript = WKUserScript(source: disableWebMenuIconScript + disableWebViewScalingScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)

        return excutableJSScript
    }

公式Doc

⭐️evaluateJavaScript()

概要

  • すでにインスタンス生成したWebViewに対してJSを反映する

使用例

  • ネイティブで取得した値をWeb側にJSで渡してあげる
  • WebView内の要素を取得してアプリに表示させる

下記コードではユーザIDを取得するJSを使用して、クロージャで取得したIDを処理しています

_viewController?.webView.evaluateJavaScript("document.querySelector('#user_id').innerText", completionHandler: { userID, error in

            if let userID = userID as? String {
                Repro.set(userID: userID) // Repro(Push配信サービス)にIDを送る処理
            }
            if let error {
                print(error)
            }
        })

注意点・備考

  • インスタンスがあって、WebView内の要素を取得したいときはWebViewの読み込みが完了してからじゃないとできない(以前、読み込み前に呼び出して何も取得できなくて、困った時がありました…)
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    print("読み込み完了")
}
  • クロージャを引数にとっているので、処理完了後に別の処理を呼び出すことも可能
func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil)

公式Doc

⭐️decidePolicyFor

概要

  • リンク先が特定外のときはブラウザで開いたりする時に使用
  • WKNavigationDelegateで定義されているメソッド

使用例

  • 下記コードではshouldAllowURL() でURLがWebViewで開くべきURLだったらtrue、ブラウザで開くべきであればfalseを返して、判断しています。
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    
        if let url = navigationAction.request.url {
            if !URLAllowList.shared.shouldAllowURL(url) { // リンク先が特定外のときはブラウザで開く
                UIApplication.shared.open(url)
                decisionHandler(.cancel)
                return
            }
        }
        decisionHandler(.allow)
    }

公式Doc

⭐️runJavaScriptAlertPanelWithMessage

概要

  • Web側で仕込まれたJSのアラートパネルをWebViewにも表示、ボタンアクションを実行できる
  • WKUIDelegateで定義

使用例

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {

        // 受け取ったメッセージでアラートを作成
        let alert = UIAlertController(title: nil,
                                      message: message,
                                      preferredStyle: .alert)

        let action = UIAlertAction(title: "OK", style: .default) { _ in
            // OKボタン押下時の処理
            completionHandler()
        }

        alert.addAction(action)
        present(alert, animated: true, completion: nil)
    }

公式Doc

⭐️runJavaScriptConfirmPanelWithMessage

概要

  • Web側で仕込まれたJSのコンファームパネルを表示、ボタンアクションを実行できる
  • WKUIDelegateで定義

使用例

    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
    
        // 受け取ったメッセージでアラートを作成
        let alert = UIAlertController(title: nil,
                                      message: message,
                                      preferredStyle: .alert)

        // キャンセルアクション
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
            completionHandler(false)
        }
        // OKアクション
        let okAction = UIAlertAction(title: "OK", style: .default) { _ in
            completionHandler(true)
        }

        alert.addAction(cancelAction)
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)
    }

公式Doc

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?