异步任务完成时,Array没有数据

时间:2017-06-01 22:07:36

标签: ios arrays json swift web-services

我一直无法下载JSON文件并返回一个对象数组,以便在我的viewcontroller的所有部分中使用。我在StackOverflow上发现了多个解决方案,当我尝试访问类中其他任何地方的数组内容但它似乎没有工作时,我将这个当前方法作为我的数据消失的解决方案。我尝试过将数据作为一个数组返回到方法中,但无法弄明白。

这是在Datatask请求完成时首先将JSON数据作为数组返回的方法。

func LoadJSONFile(from url: String, completion: @escaping ([[String: Any]])->()) {
    if let url = URL(string: url) {
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error == nil  {
                if let data = data {
                    do {
                        let json = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
                        if let content = json as? [[String: Any]] { // array of dictionaries
                            completion(content)
                        }
                    } catch {
                        // error while decoding JSON
                        print(error.localizedDescription)
                    }
                } else {
                    print("Error: no data")
                }
            } else {
                // network-related error
                print(error!.localizedDescription)
            }
            }.resume()
    }
}

这是此问题中提供的解决方案的精确副本:Answer

这是我尝试返回已完成/已填充数组的方法:

 func fillFromFile() -> [Asset_Content]{
    let url = "URLSTRING"
    var arry = [Asset_Content]()

    LoadJSONFile(from: url, completion: { (result) in
        for json in result {
            let category = json["BIGCATEGORY"] as? String
            let diagnosis = json["DIAGNOSIS"] as? String
            let perspective = json["PERSPECTIVE"] as? String
            let name = json["NAME"] as? String
            let title = json["Title"] as? String
            let UnparsedTags = json["TAGS"] as? String
            let filename = json["FILENAME"] as? String

            let tagArray = UnparsedTags?.characters.split(separator: ",")
            for tag in tagArray!{
                if(self.ListOfTags.contains(String(tag))){
                    //Do Nothing
                }else{
                    self.ListOfTags.append(String(tag))
                }
            }

            let asset = Asset_Content(category!, diagnosis!, perspective!, name!, title!, filename!)
            arry.append(asset)
            print("OLDCOUNT ==" , arry.count)
        }
    })
    print("return count ", arry.count)
    return arry
}

1 个答案:

答案 0 :(得分:0)

您对Async的工作原理感到困惑。我就是这样做的:

// The completionBlock is called with the result of your JSON file loading
func fillFromFile(completionBlock: @escaping ([Asset_Content]) -> ()) {
    let url = "URLSTRING"

    LoadJSONFile(from: url) { (result) in
        // The code inside this block would be called when LoadJSONFile is completed. this could happen very quickly, or could take a long time

        //.map is an easier way to transform/iterate over an array
        let newContentArray = json.map {

            let category = json["BIGCATEGORY"] as? String
            let diagnosis = json["DIAGNOSIS"] as? String
            let perspective = json["PERSPECTIVE"] as? String
            let name = json["NAME"] as? String
            let title = json["Title"] as? String
            let UnparsedTags = json["TAGS"] as? String
            let filename = json["FILENAME"] as? String

            let tagArray = UnparsedTags?.characters.split(separator: ",")
            for tag in tagArray!{
                if(!self.ListOfTags.contains(String(tag))){
                    self.ListOfTags.append(String(tag))
                }
            }

            let asset = Asset_Content(category!, diagnosis!, perspective!, name!, title!, filename!)
            // This is a return to the map closure. We are still in the LoadJSONFile completion block
            return asset
        }
        print("return count ", newContentArray.count)
        // This is the point at which the passed completion block is called. 
        completionBlock(newContentArray)
    }
}

希望这能解释您在自己的情况下需要做些什么。请记住,异步任务的重点是您不知道需要多长时间,等待它完成并不会停止执行当前代码块。