从 JSON 文件问题中读取国家名称
Posted
技术标签:
【中文标题】从 JSON 文件问题中读取国家名称【英文标题】:Reading countries names from JSON file problem 【发布时间】:2018-10-19 16:20:13 【问题描述】:我正在尝试使用 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
因为意外的 nil。
【问题讨论】:
你的if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
应该是as? Array<[String: Any]>
,因为最上面的对象实际上是一个数组
【参考方案1】:
JSON 以方括号 ([
) 开头,因此根对象是一个数组
不要在 Swift 中使用 NSURL
、NSArray
和 NSDictionary
和 value(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()
【讨论】:
也尽量不要使用强制展开 @AdityaSrivastava 在这种情况下,一切都非常安全。 URL 字符串是一个常量,data
如果error
是nil
并且JSON 一致,则data
有效。您甚至可以强制将向下转换为 [[String:String]]
。【参考方案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)
【讨论】:
以上是关于从 JSON 文件问题中读取国家名称的主要内容,如果未能解决你的问题,请参考以下文章