如何解析本地文件中的json数据?

时间:2019-01-08 10:18:58

标签: ios json swift api nsdictionary

我对json解析非常陌生,并尝试解析具有汽车列表的json文件,但是当我解析时,它给出nil

    func jsonTwo(){
    let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let JSON = try! JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
    print(".........." , JSON , ".......")
    let brand = JSON?["models"] as? [[String : Any]]
    print("=======",brand,"=======")
}

以及当我如下修改此代码时

    func jsonTwo(){
    let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let JSON = try! JSONSerialization.jsonObject(with: data, options: []) 
    print(".........." , JSON , ".......")
    let brand = JSON["brand"] as? [[String : Any]]
    print("=======",brand,"=======")
}

然后我得到并错误提示“ Type'Any'没有下标成员”

下面是我正在使用的json文件的示例

[{"brand": "Aston Martin", "models": ["DB11","Rapide","Vanquish","Vantage"]}]

3 个答案:

答案 0 :(得分:2)

外部对象是一个数组,请注意[],键models的值是一个String数组。

func jsonTwo() {
    let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let json = try! JSONSerialization.jsonObject(with: data) as! [[String : Any]]
    print(".........." , JSON , ".......")
    for item in json {
        let brand = item["brand"] as! String
        let models = item["models"] as! [String]
        print("=======",brand, models,"=======") 
    }
}

或更满意Decodable

struct Car: Decodable {
    let brand : String
    let models : [String]
}

func jsonTwo() {
    let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let cars = try! JSONDecoder().decode([Car].self, from: data)
    for car in cars {
        let brand = car.brand
        let models = car.models
        print("=======",brand, models,"=======") 
    }
}

通常,强烈建议不要使用!来强制展开可选选项,但是在这种情况下,代码绝不能崩溃,因为应用程序捆绑包中的文件在运行时是只读的,任何崩溃都会揭示出设计错误。

答案 1 :(得分:1)

您需要

struct Root: Codable {
    let brand: String
    let models: [String]
} 

do {

     let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
     let data = try Data(contentsOf: url) 
     let res = try JSONDecoder().decode([Root].self, from: data)
     print(res)

}
catch { 
    print(error)
}

您的问题

let JSON = try! JSONSerialization.jsonObject(with: data, options: []) 

返回Any,因此在这里JSON["brand"]

不能像字典一样使用下标

答案 2 :(得分:0)

请注意,代码中的变量JSON是对象数组。 您必须正确地投射它。

func jsonTwo(){
    let url = Bundle.main.url(forResource: "car_list", withExtension: "json")!
    let data = try! Data(contentsOf: url)
    let JSON = try! JSONSerialization.jsonObject(with: data, options: []) 
    print(".........." , JSON , ".......")
    if let jsonArray = JSON as? [[String: Any]] {
        for item in jsonArray {
            let brand = item["brand"] as? String ?? "No Brand" //A default value
            print("=======",brand,"=======")
        }
    }
}