使用 Decodable 解码自定义 Json
Decode Custom Json with Decodable
我有这个Json:
{ "first": {
"house": [
"small"
]
}, "second": {
"house": [
"small"
] }, "third": {
"car": [
"fast",
"economic"
] }, "fourth": {
"car": [
"fast",
"economic"
] }, "fifth": {
"car": [
"fast",
"economic"
],
"ice": [
"round",
"tasty"
],
"tree": [
"big",
"small"
] } }
我试图用 Decodable 建立一个结构,但我没有让它工作:
struct secondLayer: Codable {
let exchange: [String: [String]]
}
struct decodeJson: Codable {
let symbol: [String: [secondLayer]]
static func decode(jsonString: String) - [decodeJson] {
var output = [decodeJson]()
let decode = JSONDecoder()
do {
let json = jsonString.data(using: .utf8)
output = try! decode.decode([decodeJson].self, from: json!)
} catch {
print(error.localizedDescription)
}
return output
}
}
我收到这个错误:
Fatal error: 'try!' expression unexpectedly raised an error:
Swift.DecodingError.typeMismatch(Swift.Array<Any>,
Swift.DecodingError.Context(codingPath: [], debugDescription:
"Expected to decode Array<Any but found a dictionary instead.",
underlyingError: nil)): file
/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift,
line 181
我尝试了一些修改,但我没有让它工作。
错误信息
"Expected to decode Array<Any>
but found a dictionary instead."
很清楚。你想解码一个数组([decodeJson]
)但是根对象是一个字典(从{
开始)
您的代码无论如何都无法工作。 JSON 中没有键 exchange
和 symbol
。
基本上有两种解码方式 JSON:
如果所有键都是 动态的,则无法将 JSON 解码为结构。您必须将其解码为 [String:[String:[String]]]
。在这种情况下 Codable
与传统的 JSONSerialization
.
相比没有优势
struct DecodeJson: Codable {
static func decode(jsonString: String) -> [String:[String:[String]]] {
var output = [String:[String:[String]]]()
let decoder = JSONDecoder()
do {
let json = Data(jsonString.utf8)
output = try decoder.decode([String:[String:[String]]].self, from: json)
print(output)
} catch {
print(error.localizedDescription)
}
return output
}
}
或者如果序号键 first
、second
等是 static 使用伞结构
struct Root : Codable {
let first : [String:[String]]
let second : [String:[String]]
let third : [String:[String]]
let fourth : [String:[String]]
let fifth : [String:[String]]
}
struct DecodeJson {
static func decode(jsonString: String) -> Root? {
let decoder = JSONDecoder()
do {
let json = Data(jsonString.utf8)
let output = try decoder.decode(Root.self, from: json)
return output
} catch {
print(error.localizedDescription)
return nil
}
}
}
当然,您可以将 house
、car
等解码为结构,但这需要为每个结构自定义初始化程序,因为您必须使用 unkeyedContainer
[ 手动解码单个数组=26=]
我有这个Json:
{ "first": {
"house": [
"small"
]
}, "second": {
"house": [
"small"
] }, "third": {
"car": [
"fast",
"economic"
] }, "fourth": {
"car": [
"fast",
"economic"
] }, "fifth": {
"car": [
"fast",
"economic"
],
"ice": [
"round",
"tasty"
],
"tree": [
"big",
"small"
] } }
我试图用 Decodable 建立一个结构,但我没有让它工作:
struct secondLayer: Codable {
let exchange: [String: [String]]
}
struct decodeJson: Codable {
let symbol: [String: [secondLayer]]
static func decode(jsonString: String) - [decodeJson] {
var output = [decodeJson]()
let decode = JSONDecoder()
do {
let json = jsonString.data(using: .utf8)
output = try! decode.decode([decodeJson].self, from: json!)
} catch {
print(error.localizedDescription)
}
return output
}
}
我收到这个错误:
Fatal error: 'try!' expression unexpectedly raised an error:
Swift.DecodingError.typeMismatch(Swift.Array<Any>,
Swift.DecodingError.Context(codingPath: [], debugDescription:
"Expected to decode Array<Any but found a dictionary instead.",
underlyingError: nil)): file
/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift,
line 181
我尝试了一些修改,但我没有让它工作。
错误信息
"Expected to decode
Array<Any>
but found a dictionary instead."
很清楚。你想解码一个数组([decodeJson]
)但是根对象是一个字典(从{
开始)
您的代码无论如何都无法工作。 JSON 中没有键 exchange
和 symbol
。
基本上有两种解码方式 JSON:
如果所有键都是 动态的,则无法将 JSON 解码为结构。您必须将其解码为 [String:[String:[String]]]
。在这种情况下 Codable
与传统的 JSONSerialization
.
struct DecodeJson: Codable {
static func decode(jsonString: String) -> [String:[String:[String]]] {
var output = [String:[String:[String]]]()
let decoder = JSONDecoder()
do {
let json = Data(jsonString.utf8)
output = try decoder.decode([String:[String:[String]]].self, from: json)
print(output)
} catch {
print(error.localizedDescription)
}
return output
}
}
或者如果序号键 first
、second
等是 static 使用伞结构
struct Root : Codable {
let first : [String:[String]]
let second : [String:[String]]
let third : [String:[String]]
let fourth : [String:[String]]
let fifth : [String:[String]]
}
struct DecodeJson {
static func decode(jsonString: String) -> Root? {
let decoder = JSONDecoder()
do {
let json = Data(jsonString.utf8)
let output = try decoder.decode(Root.self, from: json)
return output
} catch {
print(error.localizedDescription)
return nil
}
}
}
当然,您可以将 house
、car
等解码为结构,但这需要为每个结构自定义初始化程序,因为您必须使用 unkeyedContainer
[ 手动解码单个数组=26=]