首页 > 解决方案 > 如何使用 Codable 从 Bundle 中解码 JSON 文件

问题描述

当我的 JSON 数据处于可以开始使用它的状态时,我不太确定哪里出错了。我有一些想法,但不知道如何克服它们。

这是我用来保存国家数据的 Country 结构:

struct Country: Codable {
    var id: Int
    var country: String
    var capital: String
    var nationalLanguage: String
    var population: Int
}

这是我用来解码该数据的代码。这是在我的 viewDidLoad 方法中并且正在构建,但是一旦应用程序启动就会崩溃并抛出我的 fatalError:

let url = Bundle.main.url(forResource: "countries", withExtension: "json")!
        do {
            let jsonData = try Data(contentsOf: url)
            let decoder = JSONDecoder()
            let countryStruct = try decoder.decode(Country.self, from: jsonData)
            print(countryStruct.capital)
        } catch {
            fatalError("Unable to load data")
        }
    }

这是我拖到项目导航中的 JSON 文件的片段:

[
    {
    “id”: 1,
    “country”: “United States”,
    “capital”: “Washington D.C.”,
    “nationalLanguage”: “English”,
    “population”: 328,239,523
},
{
    “id”: 2,
    “country”: “Canada”,
    “capital”: “Ottawa”,
    “nationalLanguage”: [“English”, “French”],
    “population”: 37,151,728
},

我的主视图控制器顶部还有一个 countryArray,我认为我需要使用它,但我真的不确定。

var countryArray = [Country]()

编辑:已解决 - 我在 JSON 文件中使用的引号是“智能”引号,而不是普通引号。

标签: swiftcodable

解决方案


您的 JSON 无效。

  • 正如你提到的报价无效
  • 双精度或浮点值中不允许使用逗号分隔符

此外,您的 JSON 不一致,因为在 json 数组的第一个对象中,nationalLanguage属性是 simple String,但在第二个对象中是 s 数组String

所以,你的 JSON 可能应该变成这样:

[
    {
        "id": 1,
        "country": "United States",
        "capital": "Washington D.C.",
        "nationalLanguage": ["English"],
        "population": 328239.523
    },
    {
        "id": 2,
        "country": "Canada",
        "capital": "Ottawa",
        "nationalLanguage": ["English", "French"],
        "population": 37151.728
    }
]

您的模型将更改为以下内容:

struct Country: Codable {
    var id: Int
    var country: String
    var capital: String
    var nationalLanguage: [String]
    var population: Double
}

解码将是:

if let url = Bundle.main.url(forResource: "countries", withExtension: "json") {
    do {
        let jsonData = try Data(contentsOf: url)
        let decoder = JSONDecoder()
        let countryStruct = try decoder.decode([Country].self, from: jsonData)
        print(countryStruct.capital)
    } catch {
        print(error)
    }
}

推荐阅读