Results won't append from JSON

自作多情 提交于 2020-01-03 06:18:05

问题


The JSON file I am using: https://api.myjson.com/bins/49jw2

I am using SwiftyJSON for parsing.

The variable chores wont be populated outside the method parseJson

var chores: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    tfWhat.delegate = self
    tfHowMuch.delegate = self

    loadJson()

    // wont even print
    for chore in self.chores {
        print("beschrijving: " + chore)
    }

    // prints 0
    print(chores.count)
}

func loadJson() -> Void {
    let url = NSURL(string: "https://api.myjson.com/bins/49jw2")

    NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, response, error) in
        if let error = error {
            print("Error: \(error.localizedDescription)")
        } else {
            if let data = data {
                let json = JSON(data: data)

                self.parseJson(json["appdata"]["klusjes"][])
            } else {
                print("no data")
            }
        }
    }).resume()
}

func parseJson(jsonObject : JSON) -> Void {
    for (_, value) in jsonObject {
        self.chores.append(value["beschrijving"].stringValue)
    }

    // prints:
    // beschrijving: Heg knippen bij de overburen
    // beschrijving: Auto van papa wassen
    for chore in self.chores {
        print("beschrijving: " + chore)
    }

    // prints:
    // 2
    print(chores.count)
}

回答1:


When you call an asynchronous method like NSURLSession.sharedSession().dataTaskWithURL it gets executed in the background, so whatever you launch just after this instruction is actually executed while the background task is running, so your array is not populated yet when you look at it.

A simple way to overcome this mistake is to use a "callback": a closure that will be executed once the data is available.

For example, let's add a callback

(json: JSON)->()

to the loadJson method:

func loadJson(completion: (json: JSON)->())

and place the call where the data will be available:

func loadJson(completion: (json: JSON)->()) {
    let url = NSURL(string: "https://api.myjson.com/bins/49jw2")
    NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, response, error) in
        if let error = error {
            print("Error: \(error.localizedDescription)")
        } else {
            if let data = data {
                // the callback executes *when the data is ready*
                completion(json: JSON(data: data))
            } else {
                print("no data")
            }
        }
    }).resume()
}

and use it with a trailing closure like this:

loadJson { (json) in
    // populate your array, do stuff with "json" here, this is the result of the callback
}


来源:https://stackoverflow.com/questions/36775068/results-wont-append-from-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!