在花了两天时间调查这个问题之后,我找到了解决方案,即在 swift end 中创建原生 GET 和 POST 方法,将它们暴露给 javascript。这不是最好的解决方案,但我仍然想分享它。也许它可以帮助某人。
这里是如何工作的
首先我们需要安装Alamofire 库。我们将使用它来创建请求。
github 上的自述文件包含安装它所需的所有说明
安装Alamofire后我们需要将其导入AppDelegate.swift
import Alamofire
然后我们需要在应用控制器 (AppDelegate.swift) 中创建函数,将方法暴露给 javascript
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext)
{
let requests = [String : AnyObject]()
let get: @convention(block) (String, String, [String : String]?) -> Void = { (cId:String, url:String, headers:[String : String]?) in
Alamofire.request(.GET, url, headers: headers)
.responseString { response in
jsContext.evaluateScript("requests." + cId + "(" + response.result.value! + ")")
}
}
let post: @convention(block) (String, String, [String : AnyObject]?, [String : String]?) -> Void = { (cId:String, url:String, parameters:[String : AnyObject]?, headers:[String : String]?) in
Alamofire.request(.POST, url, parameters: parameters, headers: headers)
.responseString { response in
jsContext.evaluateScript("requests." + cId + "(" + response.result.value! + ")")
}
}
jsContext.setObject(requests, forKeyedSubscript: "requests");
jsContext.setObject(unsafeBitCast(get, AnyObject.self), forKeyedSubscript: "nativeGET");
jsContext.setObject(unsafeBitCast(post, AnyObject.self), forKeyedSubscript: "nativePOST");
}
AppDelegate.swift的完整代码你可以找到here
一切就绪!现在我们可以通过 javascript 访问 nativeGET 和 nativePOST 函数了。
最后一件事是发出请求并检索响应。我不明白如何在 swift 中进行回调执行,所以我使用了 jsonp 方法,使用运行时生成的函数并将它们的名称传递给本机函数。
这是它在 javascript 中的样子
export function get(url, headers = {}) {
return new Promise((resolve) => {
const cId = `get${Date.now()}`;
requests[cId] = response => {
delete requests[cId];
resolve(response);
}
nativeGET(cId, url, headers);
});
}
export function post(url, parameters = {}, headers = {}) {
return new Promise((resolve) => {
const cId = `post${Date.now()}`;
requests[cId] = response => {
delete requests[cId];
resolve(response);
}
nativePOST(cId, url, parameters, headers);
});
}
上面的代码是用 ES6 编写的,你需要在你的 TVJS 应用中包含Promisepolifill。
现在我们可以使用我们需要的任何标头发出 GET 和 POST 请求
post('http://example.com/', {
login: 'xxx',
password: 'yyy'
}, {
'User-Agent': 'My custom User-Agent'
})