我正在从远程服务解析JSON数据。我写了一个解析过程的函数。此函数具有返回值。结果在此函数中创建并保存在全局属性中。但是当我在viewDidLoad中调用该函数时,我得到一个空结果: 这是我的代码
class ViewController: UIViewController {
var rates = [String:AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
print(getRates("USD")) // <- Gives me an empty Dictionary
}
func getRates(base: String) -> [String:AnyObject]{
let url = NSURL(string: "http://api.fixer.io/latest?base=\(base)")!
let urlSession = NSURLSession.sharedSession()
let task = urlSession.dataTaskWithURL(url) { (data, response, error) in
do{
self.rates = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! [String:AnyObject]
//print(self.rates) //<-- Gives me the right output, but i want to use it outside.
}
catch{
print("Something went wrong")
}
}
task.resume()
return self.rates //<- returns an empty Dictionary
}
我只能在函数中获得正确的结果,但我不能在外面使用它。这有什么不对?
编辑: 保护你!所有答案都有效,但有没有办法将结果存储在全局属性中,以便我可以在任何地方使用结果?假设我有一个tableView。然后我需要将结果放在全局属性
中答案 0 :(得分:1)
因为您使用NSURLSession
且任务是异步的,所以您需要使用完成处理程序。这是一个例子:
//.. UIViewController Code
var rates = [String: AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
getRates("USD") { [weak self] result in
self?.rates = result
}
}
func getRates(base: String, completion: [String: AnyObject] -> Void) {
let url = NSURL(string: "http://api.fixer.io/latest?base=\(base)")!
let urlSession = NSURLSession.sharedSession()
let task = urlSession.dataTaskWithURL(url) { (data, response, error) in
do {
let rates = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! [String:AnyObject]
completion(rates)
}
catch {
print("Something went wrong")
}
}
task.resume()
}
答案 1 :(得分:1)
您无法立即返回响应值 - 您必须等到响应从网络到达。因此,必须添加一个回调函数(块或lambda),以便在响应到达时执行。
class ViewController: UIViewController {
var rates = [String:AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
getRates("USD"){(result) in
print(result)
}
}
func getRates(base: String, callback:(result:[String:AnyObject])->()){
let url = NSURL(string: "http://api.fixer.io/latest?base=\(base)")!
let urlSession = NSURLSession.sharedSession()
let task = urlSession.dataTaskWithURL(url) { (data, response, error) in
do{
self.rates = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! [String:AnyObject]
callback(self.rates)
//print(self.rates) //<-- Gives me the right output, but i want to use it outside.
}
catch{
print("Something went wrong")
}
}
task.resume()
}
答案 2 :(得分:0)
在您的代码上尝试此操作:
class ViewController: UIViewController {
var rates = [String:AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
getRates() { (result) in
print(result)
}
}
func getRates(completion: (result: Array)) -> Void{
let url = NSURL(string: "http://api.fixer.io/latest?base=\(base)")!
let urlSession = NSURLSession.sharedSession()
let task = urlSession.dataTaskWithURL(url) { (data, response, error) in
do{
self.rates = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! [String:AnyObject]
completion(self.rates)
}
catch{
print("Something went wrong")
}
}
task.resume()
return self.rates //<- returns an empty Dictionary
}
}