Swift Codable 词典
Swift Codable Dictionary
我在进行可编码时遇到了问题。任何帮助将不胜感激。我的操场上有以下东西
我的 JSON 文件中的示例。它有更多的元素,减少了它一个更小的子集。
{
"metadata" : {
"generated" : {
"timestamp" : 1549331723,
"date" : "2019-02-04 20:55:23"
}
},
"data" : {
"CA" : {
"country-id" : 25000,
"country-iso" : "CA",
"country-eng" : "Canada",
"country-fra" : "Canada",
"date-published" : {
"timestamp" : 1544561785,
"date" : "2018-12-11 15:56:25",
"asp" : "2018-12-11T15:56:25.4141468-05:00"
}
},
"BM" : {
"country-id" : 31000,
"country-iso" : "BM",
"country-eng" : "Bermuda",
"country-fra" : "Bermudes",
"date-published" : {
"timestamp" : 1547226095,
"date" : "2019-01-11 12:01:35",
"asp" : "2019-01-11T12:01:35.4748399-05:00"
}
}
}
}
来自快速输入应用程序。它为 Datum 生成了一个字典。 json 的结构方式,国家/地区缩写没有标签。
import Foundation
// MARK: - Welcome
struct Welcome: Codable {
let metadata: Metadata?
let data: [String: Datum]?
}
// MARK: - Datum
struct Datum: Codable {
let countryID: Int?
let countryISO, countryEng, countryFra: String?
let datePublished: DatePublished?
enum CodingKeys: String, CodingKey {
case countryID = "country-id"
case countryISO = "country-iso"
case countryEng = "country-eng"
case countryFra = "country-fra"
case datePublished = "date-published"
}
}
// MARK: - DatePublished
struct DatePublished: Codable {
var timestamp: Int
var date, asp: String
}
// MARK: - Metadata
struct Metadata: Codable {
var generated: Generated
}
// MARK: - Generated
struct Generated: Codable {
var timestamp: Int
var date: String
}
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public func hash(into hasher: inout Hasher) {
// No-op
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
从我的代码中,我可以加载 json 文件,我不确定如何使用字典处理此处的数据,并且国家/地区没有国家/地区缩写名称。
guard let url = Bundle.main.url(forResource: "data", withExtension: "json") else { return 0 }
let jsonData = try Data(contentsOf: url)
注意:这是对我之前的问题的跟进:Swift Codable Parsing keyNotFound
您的数据模型已正确定义(但是,我建议更改一些名称并从属性中删除 mutability/optionality)。
一旦解析了 JSON,就没有必要保留 Dictionary
,因为键实际上是 country-iso
键下值的一部分。
因此,一旦您解码了 Root
对象,我建议您只保留 root.data.values
,这样您就可以轻松处理 Array<CountryData>
。
struct Root: Codable {
let data: [String: CountryData]
}
struct CountryData: Codable {
let countryID: Int
let countryISO, countryEng, countryFra: String
let datePublished: DatePublished
enum CodingKeys: String, CodingKey {
case countryID = "country-id"
case countryISO = "country-iso"
case countryEng = "country-eng"
case countryFra = "country-fra"
case datePublished = "date-published"
}
}
// MARK: - DatePublished
struct DatePublished: Codable {
let timestamp: Int
let date, asp: String
}
do {
let root = try JSONDecoder().decode(Root.self, from: countryJson.data(using: .utf8)!)
let countries = root.data.values
print(countries)
} catch {
error
}
我在进行可编码时遇到了问题。任何帮助将不胜感激。我的操场上有以下东西
我的 JSON 文件中的示例。它有更多的元素,减少了它一个更小的子集。
{
"metadata" : {
"generated" : {
"timestamp" : 1549331723,
"date" : "2019-02-04 20:55:23"
}
},
"data" : {
"CA" : {
"country-id" : 25000,
"country-iso" : "CA",
"country-eng" : "Canada",
"country-fra" : "Canada",
"date-published" : {
"timestamp" : 1544561785,
"date" : "2018-12-11 15:56:25",
"asp" : "2018-12-11T15:56:25.4141468-05:00"
}
},
"BM" : {
"country-id" : 31000,
"country-iso" : "BM",
"country-eng" : "Bermuda",
"country-fra" : "Bermudes",
"date-published" : {
"timestamp" : 1547226095,
"date" : "2019-01-11 12:01:35",
"asp" : "2019-01-11T12:01:35.4748399-05:00"
}
}
}
}
来自快速输入应用程序。它为 Datum 生成了一个字典。 json 的结构方式,国家/地区缩写没有标签。
import Foundation
// MARK: - Welcome
struct Welcome: Codable {
let metadata: Metadata?
let data: [String: Datum]?
}
// MARK: - Datum
struct Datum: Codable {
let countryID: Int?
let countryISO, countryEng, countryFra: String?
let datePublished: DatePublished?
enum CodingKeys: String, CodingKey {
case countryID = "country-id"
case countryISO = "country-iso"
case countryEng = "country-eng"
case countryFra = "country-fra"
case datePublished = "date-published"
}
}
// MARK: - DatePublished
struct DatePublished: Codable {
var timestamp: Int
var date, asp: String
}
// MARK: - Metadata
struct Metadata: Codable {
var generated: Generated
}
// MARK: - Generated
struct Generated: Codable {
var timestamp: Int
var date: String
}
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public func hash(into hasher: inout Hasher) {
// No-op
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
从我的代码中,我可以加载 json 文件,我不确定如何使用字典处理此处的数据,并且国家/地区没有国家/地区缩写名称。
guard let url = Bundle.main.url(forResource: "data", withExtension: "json") else { return 0 }
let jsonData = try Data(contentsOf: url)
注意:这是对我之前的问题的跟进:Swift Codable Parsing keyNotFound
您的数据模型已正确定义(但是,我建议更改一些名称并从属性中删除 mutability/optionality)。
一旦解析了 JSON,就没有必要保留 Dictionary
,因为键实际上是 country-iso
键下值的一部分。
因此,一旦您解码了 Root
对象,我建议您只保留 root.data.values
,这样您就可以轻松处理 Array<CountryData>
。
struct Root: Codable {
let data: [String: CountryData]
}
struct CountryData: Codable {
let countryID: Int
let countryISO, countryEng, countryFra: String
let datePublished: DatePublished
enum CodingKeys: String, CodingKey {
case countryID = "country-id"
case countryISO = "country-iso"
case countryEng = "country-eng"
case countryFra = "country-fra"
case datePublished = "date-published"
}
}
// MARK: - DatePublished
struct DatePublished: Codable {
let timestamp: Int
let date, asp: String
}
do {
let root = try JSONDecoder().decode(Root.self, from: countryJson.data(using: .utf8)!)
let countries = root.data.values
print(countries)
} catch {
error
}