如何使用在函数中创建的JSON结果

时间:2016-08-12 16:09:30

标签: ios json swift

我正在从远程服务解析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。然后我需要将结果放在全局属性

3 个答案:

答案 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
    }
}