Swift: WKWebView 添加javascript 界面如Android
Swift: WKWebView add javascript interface like Android
我有一个页面,我想在具有动态内容的网络视图中显示。
在Android我可以通过界面简单的做,这里是界面:
class WebAppInterface (val context: Context, val userId: Long, val type: String) {
@JavascriptInterface
fun getId(): Long {
return userId
}
@JavascriptInterface
fun getBaseUrl(): String{
return Configuration.getInstance().userConfig.getStoredBaseUrl();
}
@JavascriptInterface
fun getGetStatType(): String{
return type;
}
}
webview.addJavascriptInterface(WebAppInterface(this.applicationContext, id, statisticsType!! ), "android")
如何在 iOS 上做同样的事情,在我搜索后我得到了这个:
let contentController = WKUserContentController()
contentController.add(self, name: "android") // -> Set a listener
let config = WKWebViewConfiguration()
config.userContentController = contentController
let scriptString = "????? What write ir?"
let script = WKUserScript(source: scriptString, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
config.userContentController.addUserScript(script)
webView = WKWebView(frame: .zero, configuration: config)
以及委托方法:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message)
}
在委托方法中,它在到达关键字 android 时不打印?为什么?我误解了手术吗?
这是我的一些与 androidInterface
配合使用的 js 代码
function getSteps() {
const url = android.getBaseUrl() + 'patient/' + android.getId() + '/statistics/steps?from=' + from + '&to=' + to;
Http.open("GET", url);
Http.setRequestHeader('Authorization', 'Bearer ' + android.getToken())
Http.send();
}
如何将值注入 "android" js,就像我在 android.
中所做的那样
我通过注入手动创建的 android 对象解决了这个问题:
let scriptString = """
var android = {
getGetStatType: function() {
return 'sleep';
},
getId: function() {
return 98;
},
getBaseUrl: function() {
return 'baseUrl';
},
getToken: function() {
return 'myToken';
}
};
"""
let script = WKUserScript(source: scriptString, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true)
config.userContentController.addUserScript(script)
遗憾的是,无法从 javascript 同步调用 swift 方法来获取值。只有一种可能的方式是使用 WKUserContentController 的异步方式。在您的情况下,您很幸运,价值观不是动态的。例如,获取一些随时间变化的值是不可用的,例如GPS 位置。
SWIFT
webView.configuration.userContentController.add(self, name: "someName")
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.name, message.body)
webView.evaluateJavaScript("window.asyncResponseFromIos(123)")
}
JS
window.webkit.messageHandlers.someName.postMessage("data")
所以android和ios不可能在JS中有通用的同步接口。这就是为什么我要基于承诺制作 JS 界面。在 JS 中,我将通过调用例如从 android/ios 获得价值var value = await window.mobileAppInterface.get("someKey", "somePayload")
目标是拥有独立于应用程序平台的通用 javascript 界面。
我有一个页面,我想在具有动态内容的网络视图中显示。
在Android我可以通过界面简单的做,这里是界面:
class WebAppInterface (val context: Context, val userId: Long, val type: String) {
@JavascriptInterface
fun getId(): Long {
return userId
}
@JavascriptInterface
fun getBaseUrl(): String{
return Configuration.getInstance().userConfig.getStoredBaseUrl();
}
@JavascriptInterface
fun getGetStatType(): String{
return type;
}
}
webview.addJavascriptInterface(WebAppInterface(this.applicationContext, id, statisticsType!! ), "android")
如何在 iOS 上做同样的事情,在我搜索后我得到了这个:
let contentController = WKUserContentController()
contentController.add(self, name: "android") // -> Set a listener
let config = WKWebViewConfiguration()
config.userContentController = contentController
let scriptString = "????? What write ir?"
let script = WKUserScript(source: scriptString, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
config.userContentController.addUserScript(script)
webView = WKWebView(frame: .zero, configuration: config)
以及委托方法:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message)
}
在委托方法中,它在到达关键字 android 时不打印?为什么?我误解了手术吗? 这是我的一些与 androidInterface
配合使用的 js 代码function getSteps() {
const url = android.getBaseUrl() + 'patient/' + android.getId() + '/statistics/steps?from=' + from + '&to=' + to;
Http.open("GET", url);
Http.setRequestHeader('Authorization', 'Bearer ' + android.getToken())
Http.send();
}
如何将值注入 "android" js,就像我在 android.
中所做的那样我通过注入手动创建的 android 对象解决了这个问题:
let scriptString = """
var android = {
getGetStatType: function() {
return 'sleep';
},
getId: function() {
return 98;
},
getBaseUrl: function() {
return 'baseUrl';
},
getToken: function() {
return 'myToken';
}
};
"""
let script = WKUserScript(source: scriptString, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true)
config.userContentController.addUserScript(script)
遗憾的是,无法从 javascript 同步调用 swift 方法来获取值。只有一种可能的方式是使用 WKUserContentController 的异步方式。在您的情况下,您很幸运,价值观不是动态的。例如,获取一些随时间变化的值是不可用的,例如GPS 位置。
SWIFT
webView.configuration.userContentController.add(self, name: "someName")
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.name, message.body)
webView.evaluateJavaScript("window.asyncResponseFromIos(123)")
}
JS
window.webkit.messageHandlers.someName.postMessage("data")
所以android和ios不可能在JS中有通用的同步接口。这就是为什么我要基于承诺制作 JS 界面。在 JS 中,我将通过调用例如从 android/ios 获得价值var value = await window.mobileAppInterface.get("someKey", "somePayload")
目标是拥有独立于应用程序平台的通用 javascript 界面。