【问题标题】:Parsing User from json that has user object inside (with Codable)从内部具有用户对象的 json 中解析用户(使用 Codable)
【发布时间】:2019-05-23 16:47:41
【问题描述】:

假设我有以下用户对象:

struct User: Codable {
    let id: Int
}

并从 API 获取以下 json:

{
    "user": {
        "id": "22"
    }
}

显然,可编码的用户不会解析。除了创建包装器对象之外,还有什么方法可以做到吗?谢谢。

编辑:我得到了一些关于包装器的答案——我知道这种方法,但我对另一种方法感到好奇。是否更好的方法是无关紧要的。

【问题讨论】:

    标签: json swift codable


    【解决方案1】:

    您可以在Codable中使用containers获取nested data from JSON

    容器 = 不需要包装器对象

    struct User: Decodable {
        var id: Int
    
        enum CodingKeys: String, CodingKey {
            case user, id
        }
    
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            let user = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .user)
            let idStr = try user.decode(String.self, forKey: .id)
             id = Int(idStr) ?? 0
        }
    }
    

    使用containers,您可以使用single object 存储id 的值,而不是使用任何wrapper object

    注意:JSON 示例中,您提供的idString 类型。但在struct 定义中,您使用的是Int 类型的id。我给出的代码是在转换String to Int 之后。如果您打错字,请按原样使用 string 值。

    建议 - 将id 用作Int? 而不是Int。最好不存储任何值而不是存储垃圾值(例如:在这种情况下为 0)

    【讨论】:

    • 为什么不用decode(_:forKey:) 而不是decodeIfPresent(_:forKey:)?然后你不需要使id 可选,也不需要给它一个虚拟值。丢了就扔吧。
    • 如果 api 没有给出预期的响应怎么办?结构中可能还有其他键?
    • 我认为这取决于用户在该特定用例中的预期。
    • 鉴于 OP 将 id 设为非可选,那么它应该在那里,如果不是,那将是一个例外。因此decode 优于decodeIfPresent。 OP 可以捕获异常并根据需要处理丢失的 id。
    • 好的。更正了。
    【解决方案2】:

    两个错误:缺少根对象,id 的类型是String(注意双引号)。

    使用Codable,您必须始终从顶部解析 JSON

    struct Root : Codable {
        let user : User
    }
    
    struct User : Codable {
        let id: String
    }
    

    或者解码为字典,但这使得Codable 的使用毫无意义。

    【讨论】:

    • 他问如何没有包装。但是,包装器是迄今为止最简单的方法。
    【解决方案3】:

    最简单的 JSON 模型:

    import Foundation
    
    // MARK: - UserModel
    struct UserModel: Codable {
    let user: User
    }
    
    // MARK: - User
    struct User: Codable {
    let id: String
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多