json - Swift 4 可编码;如何使用单个根级 key 解码对象

标签 json swift deserialization swift4 codable

我正在使用带有 JSON 数据的 Swift 4 Codable 协议(protocol)。我的数据被格式化为在根级别有一个键,其对象值包含我需要的属性,例如:

{
  "user": {
    "id": 1,
    "username": "jdoe"
  }
}

我有一个 User 结构可以解码 user 键:

struct User: Codable {
  let id: Int
  let username: String
}

由于 idusernameuser 的属性,而不是在根级别,我需要像这样创建一个包装器类型:

struct UserWrapper: Codable {
  let user: User
}

然后我可以通过 UserWrapper 解码 JSON,并且 User 也被解码。看起来有很多冗余代码,因为我需要对我拥有的每种类型都进行额外的包装。有没有办法避免这种包装模式或更正确/优雅的方式来处理这种情况?

最佳答案

Ollie 的回答绝对是解决这种情况的最佳方式,但它确实将一些知识推送给了调用者,这可能是不可取的。它也不是很灵活。我仍然认为这是一个很好的答案,并且正是您想要的,但这是探索自定义结构编码的一个很好的简单示例。

我们怎样才能使它正常工作:

let user = try? JSONDecoder().decode(User.self, from: json)

我们不能再使用默认的一致性了。我们必须构建自己的解码器。这有点乏味,但并不难。首先,我们需要将结构编码为 CodingKeys:

struct User {
    let id: Int
    let username: String

    enum CodingKeys: String, CodingKey {
        case user // The top level "user" key
    }

    // The keys inside of the "user" object
    enum UserKeys: String, CodingKey {
        case id
        case username
    }
}

这样,我们可以通过拉出嵌套容器手动解码User:

extension User: Decodable {
    init(from decoder: Decoder) throws {

        // Extract the top-level values ("user")
        let values = try decoder.container(keyedBy: CodingKeys.self)

        // Extract the user object as a nested container
        let user = try values.nestedContainer(keyedBy: UserKeys.self, forKey: .user)

        // Extract each property from the nested container
        id = try user.decode(Int.self, forKey: .id)
        username = try user.decode(String.self, forKey: .username)
    }
}

但我绝对会按照 Ollie 的方式来解决这个问题。

有关更多信息,请参阅 Encoding and Decoding Custom Types .

关于json - Swift 4 可编码;如何使用单个根级 key 解码对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44715494/

相关文章:

javascript - 用于检索 json 数据的 Angular Controller

uitableview - popToRootViewControllerAnimated 没有更新 UITableView

swift - 为什么我的 firestore 集合返回 0 个文档

objective-c - 如何在 Xcode 中将源代码连接到已编译的框架

javascript - 移动设备上性能更好的 JSON 替代方案

java - 如何将第三方api中的JSON对象转换为本地POJO

kotlin - 使用Jackson使用模式反序列化Property

javascript - Chrome 和 IE 已解析/未解析 JSON 响应

javascript - 以 JSON 格式发布数据

javascript - 从 json url 获取数据