web-dev-qa-db-ja.com

UIWebViewからSwiftへのJavaScript呼び出し

私はUIWebViewのJavaScript関数からSwift iOS 10への呼び出しを行おうとしています。これを試すために非常に基本的なプロジェクトをセットアップしました。コードは以下のとおりです。

import UIKit

class ViewController: UIViewController, UIWebViewDelegate  {    
  @IBOutlet var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = Bundle.main.url(forResource: "products", withExtension: "html")
        let request = NSURLRequest(url: url! as URL)
        webView.loadRequest(request as URLRequest)
    }

    @IBAction func closeDocumentViewer() {
        displayView.isHidden = true;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

JavaScript関数から文字列を受け取るために1つだけの場合、上記に何を追加する必要がありますか?

7
Tony Goodchild

myawesomeappなどのカスタムURL Schemeを使用し、次のものを使用してリクエストをインターセプトする必要があります。

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool

window.location=myawesomeapp://hello=worldを使用してネイティブコードの呼び出しを開始し、ネイティブコードのrequest.URL.queryから渡したクエリパラメータを取得します。

詳細については、ここでUIWebViewsに関する私の質問を参照してください。 WKWebViewへのJavaScript同期ネイティブ通信

3
paulvs

代わりにWKWebViewを使用することを検討することをお勧めしますUIWebView。その後、カスタムURLスキームを登録する必要はありません。さらに、UIWebViewは廃止され、WKWebViewには多くの利点があります。特に、パフォーマンスとレンダリングは別のプロセスで実行されるためです。

Apple WKWebViewを使用するためのドキュメントと推奨事項へのリンク https://developer.Apple.com/reference/webkit/wkwebview/ へのリンク

重要

IOS 8.0とOS X 10.10以降、WKWebViewを使用して>アプリにWebコンテンツを追加します。 UIWebViewまたはWebViewを使用しないでください。

つまり、ネイティブからJavaScriptへのブリッジを設定するのは非常に簡単です。

import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
   var webView: WKWebView?
    override func loadView() {
        super.loadView()

        webView = WKWebView(frame: self.view.frame)
        webView?.configuration.userContentController.add(self, name: "scriptHandler")

        self.view.addSubview(webView!)
    }

    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print("Message received: \(message.name) with body: \(message.body)")
    }
// rest of code
}

次に、JavaScriptコードでそれを呼び出します。

window.webkit.messageHandlers["scriptHandler"].postMessage("hello");

私はこれを活用し、いくつかの豪華なJavaScript構文を追加するライブラリを作成しました。 https://github.com/tmarkovski/BridgeCommander

それを使用するには、プロジェクトを参照する(またはSwiftとjavascriptファイルをXcodeプロジェクトに追加する)だけで、

    webView = WKWebView(frame: self.view.frame)
    let commander = SwiftBridgeCommander(webView!)

    commander.add("echo") {
        command in
        command.send(args: "You said: \(command.args)")
    }

その後、次のようなJavaScriptでコールバック構文を使用できるようになります

var commander = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
        // success callback
    }, function(error) { 
        // error callback
});
17

WKScriptMessageHandlerを使用して、JavaScriptからSwift関数を呼び出すことができます

WKScriptMessageHandlerプロトコルに準拠したクラスは、Webページで実行されているJavaScriptからメッセージを受信するためのメソッドを提供します。

イベントのリスナーをWKUserContentControllerに追加する必要があります

 let contentController = WKUserContentController()
    contentController.add(self, name: "loginAction”)

JavaScriptから送信されたコンテンツを受信するには、そのuserContentControllerを実装する必要があります。例として。現時点で必要な「ログアウト」のみに制限します。

  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {       
       if message.name == "logout" {
           print("JavaScript is sending a message \(message.body)")
       }
   }

そしてJavaScriptの端から、彼らはこのように実装する必要があります:

 function sendLogoutAction() {
       try {
           webkit.messageHandlers.logout.postMessage("logout");
       } catch(err) {
           console.log('The native context does not exist yet');
       }
    }
0
Anshul Jain