我试图发送一个请求,以通过Alamofire从Amazon获得JSON,但它异步化。它在获得亚马逊的响应之前又回到呼叫者功能。
public func getJSON(fileName: String) -> JSON?{
let url = "http://s3.eu-west-3.amazonaws.com" + fileName
print(self.json)
if self.json == nil {
Alamofire.request(url)
.responseJSON { response in
if let result = response.result.value {
self.json = JSON(result)
}
}
return self.json
}
else{
return nil
}
}
public func initTableView(){
let myJson = AmazonFiles.shared.getJSON(fileName: "/jsonsBucket/myJson.json")
print(myJson["id"])
}
initTableView
功能中的对象myJson
始终为零。
我如何解决此问题?
而不是返回JSON?在方法签名中,使用这样的完成闭合:
public func getJSON(fileName: String, completion: ((JSON?) -> Void)?) {
let url = "http://s3.eu-west-3.amazonaws.com" + fileName
Alamofire.request(url).responseJSON { response in
if let result = response.result.value {
completion?(JSON(result))
} else {
completion?(nil)
}
}
}
并以这样的方式调用方法:
getJSON(fileName: "/jsonsBucket/myJson.json") { json in
print(json)
}
或:
getJSON(fileName: "/jsonsBucket/myJson.json", completion: { json in
print(json)
})
您需要实现一个完成处理程序,看看这篇文章。
完成处理程序是我们提供的代码,当它带回这些项目时被调用。在这里,我们可以处理呼叫的结果:错误检查错误,在本地保存数据,更新UI,无论如何。
typealias completionHandler = (JSON?) -> Void // this is your completion handler
public func getJSON(fileName: String, completionHandler: @escaping completionHandler) -> JSON?{
let url = "http://s3.eu-west-3.amazonaws.com" + fileName
if self.json == nil {
Alamofire.request(url)
.responseJSON { response in
if let result = response.result.value {
completionHandler(json) // this will fire up your completion handler,
}
}
}
else{
completionHandler(nil)
}
}
您可以这样使用。
getJSON(fileName: "fileName") { (json) in
// this will fire up when completionhandler clousre in the function get triggered
//then you can use the result you passed whether its JSON or nil
guard let result = json else { return } // unwrap your result and use it
print(result)
}