1

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

IOS 斯威夫特

在我看来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 Reference 错误:未找到变量 sendComment。

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

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

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

4

2 回答 2

0

使用此代码调用js函数Objectiv-C

 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)
    }
}
于 2018-11-02T06:11:07.863 回答
0

我终于解决了这个问题

问题

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

解决方案

在 func 中添加所有配置、首选项和 userContentControllerloadView()并通过 https 端点或viewDidLoad()func中的本地 html 文件加载 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 用于在 viewController 类中接收 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)
            }
     })
   }
}
于 2018-11-06T13:02:33.470 回答