Swift 4.1 Decodable 无法使用nestedContainer 解码嵌套数组

And*_*nie 1 ios swift codable

尝试编写一个简单的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)

我不确定问题是什么,因为我显然(在我看来)要求一系列武器,但它认为我无论如何都在寻找字典。

想知道是否有人对我缺少的东西有任何见解。

vad*_*ian 6

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)