我一直无法下载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
}
答案 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)
}
}
希望这能解释您在自己的情况下需要做些什么。请记住,异步任务的重点是您不知道需要多长时间,等待它完成并不会停止执行当前代码块。