如何将swift对象传递给javascript(WKWebView / swift)

我正在努力将数据从swift传递到WKWebView中的javascript

我有一个自定义类:

class AllInfo: AnyObject { var title = "Special Title" var description = "Special Description" } 

并初始化它

 var info = AllInfo() 

然后我有一个WKWebView,我通过它传递一个WKUserScript,我有一个源属性:

 source: "changeDisplay('\(info)')" 

我的问题是如何在javascript中访问此对象。 我试图像javascript对象一样访问它以及没有运气的关联数组。 这是jsfunction:

 function changeDisplay(passedInfo) { document.querySelector('h1').innerHTML = passedInfo.title document.querySelector('h2').innerHTML = passedInfo.description } setTimeout(function () {changeDisplay();}, 5000); 

编辑:当我尝试访问这样的对象时,我得到了未定义。

所以我的问题是:

我可以将AnyObject传递给JavaScript并访问它吗? 如果没有,我应该使用什么类型的swift类,以便我可以轻松传递它。

我很想在swift中创建一个javascript对象并传递它,但我觉得有更好的方法。

谢谢

编辑:我回答了我如何能够以下面的JSON传递数据。

将本机对象传递给javascript非常复杂,特别是对于在多进程模式下运行的WKWebView。 有关本机对象的任何操作都需要跨越进程边界。 WKWebView在native和javascript之间没有语言绑定支持。 但是,WKWebView支持消息传递API。 你必须将它包装在JS和native之间的复杂交互中。

我创建了一个名为XWebView的项目,它基于WKWebView的原始消息传递提供语言绑定样式API。 它是用Swift编写的。

关于您的示例,首先必须在javascript命名空间中注入对象:

 let webView = WKWebView(frame: frame, configuration: WKWebViewConfiguration()) webView.loadPlugin(AllInfo(), namespace: "someInfo") 

您可以在javascript中访问该对象:

 console.log(window.someInfo.title); window.someInfo.title = "Some title"; 

要将Swift对象公开给javascript,属性和方法必须是动态分派。 这意味着,属性必须是动态的 ,方法必须具有@objc属性。 (有关动态分派,请参阅https://developer.apple.com/swift/blog/?id=27 )。 简单来说,inheritance自NSObject。

在.swift中,定义并调用此方法

 func evaluateJavaScriptForData(dictionaryData: [String: AnyObject]) { // Convert swift dictionary into encoded json let serializedData = try! NSJSONSerialization.dataWithJSONObject(dictionaryData, options: .PrettyPrinted) let encodedData = serializedData.base64EncodedStringWithOptions(.EncodingEndLineWithLineFeed) // This WKWebView API to calls 'reloadData' function defined in js webView.evaluateJavaScript("reloadData('\(encodedData)')") { (object: AnyObject?, error: NSError?) -> Void in print("completed with \(object)") } } 

在.js / .html文件中

 function reloadData(sBinaryParam) { // This 'atob' decodes the Base64 encoded data sent by swift var sDecodedParam = window.atob(sBinaryParam); var oData = JSON.parse(sDecodedParam); // This 'oData' is your js object (dictionary) return true; } 

回答我自己的问题:

JSON(可能)是传递给javascript的最佳类型。

我删除了类,而是创建了一个类似NSDictionary(或者将类作为NSDictionary键入):

 var allInfoRawSwift = ["title": "This is the title", "description": "this is the description"] 

然后将其转换为JSON(如果是swift 2,则在do / catch中):

 let allInfoJSON = try NSJSONSerialization.dataWithJSONObject(allInfoRawSwift, options: NSJSONWritingOptions(rawValue: 0)) 

将JSON转换为字符串:

 let allInfoJSONString = NSString(data: allInfoJSON, encoding: NSUTF8StringEncoding)! 

然后添加souce propery像:

 source: "changeDisplay(\(allInfoJSONSting))" 

要进行调试,最好让您的函数只为您传递的内容设置一个全局变量,然后使用safari的开发人员模式访问Web控制台并检查全局变量。

如果有更好的方法,或者您有任何提示,请告诉我。

谢谢

这是来自Ashok接受的答案的Swift代码的更新,与Swift 3.0.2兼容:

 func evaluateJavaScriptForData(dictionaryData: [String: AnyObject]) { // Convert swift dictionary into encoded json let serializedData = try! JSONSerialization.data(withJSONObject: swiftObject, options: .prettyPrinted) let encodedData = serializedData.base64EncodedString(options: .endLineWithLineFeed) // This WKWebView API to calls 'reloadData' function defined in js webView.evaluateJavaScript("reloadData('\(encodedData)')", completionHandler: { result, error in print("Completed Javascript evaluation.") print("Result: \(result)") print("Error: \(error)") }) }