解析可编码类并避免重复

时间:2018-12-20 20:11:05

标签: swift codable

我有一个JSON响应,如下所示:

{
  "http_status": 200,
  "success": true,
  "has_error": false,
  "error": [
    ""
  ],
  "response": {
    "token": "",
    "verified": false,
    "message": ""
  }
}

就我可以说的应用API使用情况而言,http_status,成功,has_error,错误在所有APIS之间共享,因此我将创建一个Codable类来处理它,但是响应可能是不同的模型,所以这就是我正在尝试做。

我创建了如下的通用响应类,因此该类可用于项目中的所有api,以避免重复相同的类但使用不同的名称:

class GeneralResponse:Codable {

    let http_status: Int?
    let success, has_error: Bool?
    let error: [String]?

    enum CodingKeys: String, CodingKey {
        case http_status = "http_status"
        case success = "success"
        case has_error = "has_error"
        case error = "error"
    }

    init(http_status: Int?, success: Bool?, has_error: Bool?,error: [String]?) {
        self.http_status = http_status
        self.success = success
        self.has_error = has_error
        self.error = error
    }

}

现在我已经创建了响应类,该类现在将处理注册响应:

class RegistrationResponseDetails: Codable {
    let token: String?
    let verified: Bool?
    let message: String?

    init(token: String?, verified: Bool?, message: String?) {
        self.token = token
        self.verified = verified
        self.message = message
    }
}

并且可以说我需要解析注册的响应,所以这就是我所做的,我创建了一个类并使用了它们:

class RegistrationResponse: Codable {

    let generalResponse:GeneralResponse?
    let response: RegistrationResponseDetails?

    init(generalResponse: GeneralResponse?, response: RegistrationResponseDetails?) {
        self.generalResponse = generalResponse
        self.response = response
    }
}

因此,我将主要使用RegistrationResponse来解析响应,该响应将解析“ generalResponse”,其中包括http_status,成功,has_error,错误,然后响应将解析所需的响应对象。

但是在某个时候,generalResponse对象始终为nil,并且response的数据已正确解析,我该怎么做才能使generalResponse能够在不重复的情况下进行解析,因为在每个api中我都会拥有generalResponse对象,因此可以解决它吗?

注意:我正在使用Alamofire作为网络库。

3 个答案:

答案 0 :(得分:1)

简单的情况

class Main:Decodable { 
    let name:String?   // insert all shared vars 
} 

class Sub:Main { 
   let id:String? 
} 

这将解析

{
     "name" : "rr" , 
     "id" : "oo"  
}

答案 1 :(得分:1)

您可以将GeneralResponse设为通用名称,并在解析响应时告诉它使用哪种类型:

class GeneralResponse<T: Codable>: Codable {
    let http_status: Int?
    let success, has_error: Bool?
    let error: [String]?
    let response: T?
}

class RegistrationResponseDetails: Codable {
    let token: String?
    let verified: Bool?
    let message: String?
}

然后,您可以在解析json时为其提供内部响应类:

let generalResponse = try JSONDecoder().decode(GeneralResponse<RegistrationResponseDetails>.self, from: jsonData)
// generalResponse.response is of type RegistrationResponseDetails?

答案 2 :(得分:1)

首先是

  

http_status,成功,has_error,错误在所有APIS之间共享

为什么类属性是可选的?


如果上述键相同,但键response的值不同,请使用泛型。

在大多数情况下,struct个就足够了。

struct JSONParser<T : Decodable> {

    struct Response<U : Decodable> : Decodable {
        let httpStatus: Int
        let success, hasError: Bool
        let error: [String]
        let response : U
    }

    let responseData : Response<T>

    init(data: Data) throws {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        responseData = try decoder.decode(Response.self, from: data)
    }
}

然后创建不同的结构,例如

struct RegistrationResponseDetails : Decodable {
    let token: String
    let verified: Bool
    let message: String
}

并解析

let parser = try JSONParser<RegistrationResponseDetails>(data: data)
let registrationResponseDetails = parser.responseData.response