从JSON文件问题中读取国家/地区名称

时间:2018-10-19 16:20:14

标签: ios json swift xcode

我正在尝试使用swift从json文件加载和解析国家/地区名称,但我不能

这是我尝试读取的文件格式:Countries JSON File

我要执行此任务的代码:

func getJsonFromUrl(){
    let url = NSURL(string: COUNTRIES_URL)
    URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
        if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
            if let countries_array = jsonObj!.value(forKey: "name") as? NSArray {
                for country in countries_array {
                    if let countryDict = country as? NSDictionary {
                        if let name = countryDict.value(forKey: "name") {
                            self.countries_names.append((name as? String)!)
                        }
                    }
                }
            }
            OperationQueue.main.addOperation ({
                self.showNames()
            })
        }
    }).resume()
}

但是,当我运行它时,它在以下一行中给我一个错误:if let countries_array = jsonObj!.value(forKey: "name") as? NSArray { 因为出乎意料的零。

2 个答案:

答案 0 :(得分:2)

这是您需要的数组而不是字典

if let dat = data {
   if let jsonObj = try? JSONSerialization.jsonObject(with: dat, options:[]) as? [[String:String]]{
   jsonObj.forEach { print($0["name"]) }    
}

或使用Codable

let res = try? JSONDecoder().decode([[String:String]].self,from:data)

或带有模型

struct Root: Codable {
  let name : String
}

let res = try? JSONDecoder().decode([Root].self,from:data)

答案 1 :(得分:2)

JSON以方括号([)开头,因此根对象是数组

在Swift中不要使用NSURLNSArrayNSDictionaryvalue(forKey

并处理可能的错误。

func getJsonFromUrl() {
    let url = URL(string: COUNTRIES_URL)!
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) -> Void in
        if let error = error { print(error); return }
        do {
            if let countriesArray = try JSONSerialization.jsonObject(with: data!) as? [[String:String]] {
                for country in countriesArray {
                    self.countries_names.append(country["name"]!)
                }
            }
        } catch { print(error) }
        OperationQueue.main.addOperation ({
            self.showNames()
        })
    }).resume()
}

或者更方便地使用Decodable

struct Country : Decodable {
    let name : String
}

func getJsonFromUrl() {
    let url = URL(string: COUNTRIES_URL)!
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) -> Void in
        if let error = error { print(error); return }
        do {
            let countries = try JSONDecoder().decode([Country].self, from: data!)
            self.countries_names = countries.map{$0.name}
        } catch { print(error) }
        OperationQueue.main.addOperation ({
            self.showNames()
        })
    }).resume()
}