Swift:WKWebView 添加类似 Android 的 javascript 界面
Posted
技术标签:
【中文标题】Swift:WKWebView 添加类似 Android 的 javascript 界面【英文标题】:Swift: WKWebView add javascript interface like Android 【发布时间】:2019-07-25 14:09:14 【问题描述】:我有一个页面,我想在 web 视图中显示动态内容。
在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 上所做的那样。
【问题讨论】:
可能重复:***.com/questions/51998861/… 【参考方案1】:我通过注入像这样手动创建的 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)
【讨论】:
【参考方案2】:不幸的是,无法从 javascript 同步调用 swift 方法来获取值。只有一种可能的方式是使用 WKUserContentController 的异步方式。在您的情况下,您很幸运,价值观不是动态的。例如,它不能用于获得一些随时间变化的值,例如GPS 位置。
斯威夫特
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")
所以在 JS 中不可能有 android 和 ios 的通用同步接口。这就是为什么我要基于 Promise 制作 JS 接口。在 JS 中,我将通过调用例如从 android/ios 获得价值。 var value = await window.mobileAppInterface.get("someKey", "somePayload")
目标是拥有独立于应用平台的通用javascript接口。
【讨论】:
以上是关于Swift:WKWebView 添加类似 Android 的 javascript 界面的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 10 + Swift 3 中以编程方式在我的 WKWebView 上方添加 UILabel
在 iOS 9 中遇到 WKWebview 和 UIWebView 问题