从 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)
}
})
}
}
我正在开发一个 ios 应用程序,它使用 WKWebview 来显示我的网络应用程序。我的前端有一个简单的按钮,它通过 window.webkit.messageHandlers.isLocationPresent.postMessage("checkLocation")
.
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 方面,我通过
实现了 userContentControllerfunc 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
加载视图
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)
}
})
}
}