在Swift中使用Codable时如何保持灵活的结构

时间:2019-12-29 09:48:49

标签: swift codable jsondecoder

我有一个表示用户对象的API响应结构,如下所示:

{
    "statuscode": 200,
    "response_type": 3,
    "errormessage": null,
    "detailresponse": {
        "id": "2",
        "shopifyautosync": null,
        "platformfeepercentage": null,
        "invited": null,
        "requiresyoutubesocialmediaupdate": 1,
        // Other properties ...
}

我正在使用JSONDecoder()。decode解码为以下结构:

import Foundation

class Response: Decodable {
    var statuscode: Int?
    var response_type: Int?
    // Other properties
    var detailresponse: User?
}

import Foundation

class User: Codable {
    var id: String?
    var street: String?
    var supporturl: String?
    var verifiedaccount: Int?
    var showfeatureupdatemodal: Int?
    var admin: Int?
    var email: String?
    // Other properties
}

这就是我解码的方式:

let response = try JSONDecoder().decode(Response.self, from: jsonData)

我现在的主要问题是Response类的detailresponse属性被硬连接到User结构。但是,我在设置时需要一些灵活性, 因为当调用不同的端点(例如,合作对象而不是用户对象)时,detailresponse当然会携带其他数据结构。

是否有一种优雅的方法来使detailResponse保持在Response类内部灵活而不是硬接线呢?还是用一般更好的方法来解决问题?

2 个答案:

答案 0 :(得分:1)

您需要使用泛型

class Response<T:Decodable>: Decodable {
    var statuscode: Int?
    var response_type: Int?
    // Other properties
    var detailresponse: T?
}

然后

let response = try JSONDecoder().decode(Response<User>.self, from: jsonData)

答案 1 :(得分:1)

这是泛型的用例:

class Response<T: Decodable>: Decodable {
   var statuscode: Int?
   var response_type: Int?
   // Other properties
   var detailresponse: T?
}

请注意,几乎没有理由使属性可变。它们应该是let。另外,struct在这里可能是更好的选择。而且我认为应该减少可选内容,因为这应该是成功的应对措施。