如何在Swift中加载json之前等待函数执行?

时间:2017-06-09 13:43:42

标签: arrays json swift asynchronous swift3

我从url获取json文件,然后,所有json输出都将添加到数组中。当我打印数组时,它说数组是空的,但实际上数组不是空的我知道。如果我使用:DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { },那么,我可以打印数组。

获取json并将其值添加到数组的代码:

var allTags:Array<String> = []
func getJSON(getUrl:URL){

    let url:URL = getUrl
    let session = URLSession.shared

    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

    let task = session.dataTask(with: request as URLRequest) {
        (data, response, error) in

        let dataString =  String(data: data, encoding: String.Encoding.utf8)!

        do {
            let data = Data(dataString.utf8)
            let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
            for dict in dictionaries {
                let tags = dict["Tags"] as? [String] ?? []
                for tag in tags {
                    allTags.append(tag)
                }
            }
        }
    }task.resume()
}

getJSON(getUrl: self.jsonUrl())

print(self.allTags.count) //it prints 0, but there are some data I know

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 
    print(self.allTags.count)  //it prints 168
}

2 个答案:

答案 0 :(得分:0)

使用回调:

var allTags:Array<String> = []
func getJSON(getUrl:URL, callback: @escaping () -> Void) {
    let url:URL = getUrl
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
    let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
        let dataString =  String(data: data, encoding: String.Encoding.utf8)!
        do {
            let data = Data(dataString.utf8)
            let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
            for dict in dictionaries {
                let tags = dict["Tags"] as? [String] ?? []
                for tag in tags {
                    allTags.append(tag)
                }
            }
            callback()
        }
    }
    task.resume()
}

getJSON(getUrl: self.jsonUrl()) {
    print(self.allTags.count) // Should work now
}

答案 1 :(得分:0)

    var allTags:Array<String> = []
    func getJSON(getUrl:URL, completion: @escaping () -> ()) {

        let url:URL = getUrl
        let session = URLSession.shared

        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

        let task = session.dataTask(with: request as URLRequest) {
            (data, response, error) in

            let dataString =  String(data: data, encoding: String.Encoding.utf8)!

            do {
                let data = Data(dataString.utf8)
                let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
                for dict in dictionaries {
                    let tags = dict["Tags"] as? [String] ?? []
                    for tag in tags {
                        allTags.append(tag)
                    }
                }
            completion()
            }
        }task.resume()
    }

    getJSON(getUrl: self.jsonUrl()) { [weak self] in
        guard let strongSelf = self else { return }
        print(strongSelf.allTags.count)
    }