尝试编写一个简单的Swift 4.1使用 Codable 来解析json.
我有一个struct这样的:
struct GameCharacter : Codable {
var name : String
var weapons : [Weapon]
enum CodingKeys : String, CodingKey {
case name
case weapons
}
init(from decoder: Decoder) {
do {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
let weaponsContainer = try container.nestedContainer(keyedBy: Weapon.CodingKeys.self, forKey: .weapons)
self.weapons = try weaponsContainer.decode([Weapon].self, forKey: .weapons)
} catch let error {
print("error: \(error)")
fatalError("error is \(error)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一个像这样:
struct Weapon : Codable {
var name : String
enum CodingKeys : String, CodingKey {
case name
}
init(from decoder: Decoder) {
do {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
} catch let error {
print("error: \(error)")
fatalError("error is \(error)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我也有这样struct的包装器:
struct Game : Codable {
var characters : [GameCharacter]
enum CodingKeys : String, CodingKey { case characters }
}
Run Code Online (Sandbox Code Playgroud)
json 数据如下所示:
{
"characters" : [{
"name" : "Steve",
"weapons" : [{
"name" : "toothpick"
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
但是,我总是收到 typeMismatcherror 错误:
错误: typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "characters", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected to解码字典,但找到了一个数组。”,underlyingError: nil))
在这一行:
let weaponsContainer = try container.nestedContainer(keyedBy: Weapon.CodingKeys.self, forKey: .weapons)
Run Code Online (Sandbox Code Playgroud)
我不确定问题是什么,因为我显然(在我看来)要求一系列武器,但它认为我无论如何都在寻找字典。
想知道是否有人对我缺少的东西有任何见解。
nestedContainers仅当您想将子字典或子数组解码到父结构中时才需要 - 例如将weapons对象解码到Game结构中 - 情况并非如此,因为您声明了所有嵌套结构。
要解码 JSON,您可以省略所有 CodingKeys 和初始值设定项,利用 的魔法Codable,这就足够了:
struct Game : Codable {
let characters : [GameCharacter]
}
struct GameCharacter : Codable {
let name : String
let weapons : [Weapon]
}
struct Weapon : Codable {
let name : String
}
Run Code Online (Sandbox Code Playgroud)
并称之为
do {
let result = try JSONDecoder().decode(Game.self, from: data)
print(result)
} catch { print(error) }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2244 次 |
| 最近记录: |