从 webapp 收到消息时如何从 WKWebview 调用 javascript 函数

How to call a javascript function from WKWebview when message is received from webapp

我正在开发一个 ios 应用程序,它使用 WKWebview 来显示我的网络应用程序。我的前端有一个简单的按钮,它通过 window.webkit.messageHandlers.isLocationPresent.postMessage("checkLocation").

将消息发送到 WKWebview

IOS Swift

在我看来DidLoad

let configuration = WKWebViewConfiguration()
 let controller = WKUserContentController()

// name of handler called from js code
controller.add(self,name: "isLocationPresent")
configuration.userContentController = controller

let webView = WKWebView(frame: self.view.frame,configuration:configuration)

在 ios 方面,我通过

实现了 userContentController
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 
  if message.name == "isLocationPresent" {
// my logic for checking if location service is available
// if location is present the method returns true else false
  let isGpsAvailable:Bool = self.checkLocationServiceState()
        if isGpsAvailable {
            webView.evaluateJavaScript("sendComment(\(isGpsAvailable ))", completionHandler: {(result,error) in
                print(result)
                print(error)
            })
        }
      else{
           // perform other logic there 
         } 
     }
}

Javascript

 document.getElementById('click').onclick = function() {
    window.webkit.messageHandlers.isLocationPresent.postMessage("checkLocation").
}

function sendComment(aval) {
if(aval) {
  makeRequest()
}
else {
// logic to handle if false
}
}

但每次我单击按钮时,evaluateJavascript 总是抛出 Javascript 引用错误:未找到变量 sendComment。

Web 应用程序是动态的,每个 html 元素都是由 javascript 创建的。 我有三个视图,当用户单击列表时,他会转到第二个视图,其中呈现 click 按钮。

因此,在页面加载时调用 webview 将不起作用,因为按钮元素未在我的第一个视图中呈现

sendComment() 函数只能在 ios 按钮被点击时被调用。我还有其他用例,当用户仅在前端执行操作时,函数调用应该在 ios 中进行。

使用此代码调用 Objectiv-C

中的 js 函数
 NSString * scriptSource = [NSString stringWithFormat:@"sendComment(%@)",msg];
[_WebView evaluateJavaScript:scriptSource completionHandler:^(NSString *result, NSError *error)
 {
     if(result != nil){
         NSLog(@"Result: %@",result);
     }

 }];

Swift:

var scriptSource = "sendComment(\(msg))"
webView.evaluateJavaScript(scriptSource) { (result, error) in
    if result != nil {
        print(result)
    }
}

我终于解决了这个问题

问题

我在 view.didLoad() 函数中实现我的配置和控制器。

解决方案

loadView() func 中添加所有配置、首选项和 userContentController,并通过 https 端点或本地 html 文件在 viewDidLoad() func

中加载 webview

加载视图

override func loadView() {
    super.loadView()

    let preferences = WKPreferences()
    preferences.javaScriptEnabled = true

    let configuration = WKWebViewConfiguration()
    configuration.preferences = preferences

    let userContentController = WKUserContentController()

    userContentController.add(self,name:"sendComment")

    configuration.userContentController = userContentController



    self.view.addSubview(webView)
    self.view.sendSubviewToBack(webView)

    webView = WKWebView(frame: view.bounds, configuration: configuration)

    view = webView
}

查看已加载

这是我的override func viewDidLoad()

override func viewDidLoad() {
        super.viewDidLoad()
        print("view will load")
        // Do any additional setup after loading the view, typically from a nib.

        let request = URLRequest(url:URL(string:"your-url")!)
        webView.navigationDelegate = self

        webView.load(request)
    }

userContentController

我的 userContentController 用于在 viewController class

中接收 JS 消息
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            print(message.name)
            if message.name == "sendComment" {
              let result:String = "Marlboro"

                webView.evaluateJavascript("sendComment('\(result)')", completionHandler:{(result , error) in
            if error == nil {
               print("success")
            } 
           else {
             print("error in executing js ", error)
            }
     })
   }
}