代码之家  ›  专栏  ›  技术社区  ›  AaoIi

解析可编码类并避免重复

  •  1
  • AaoIi  · 技术社区  · 7 年前

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

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

    据我所说,对于一个应用程序API的使用,http_状态,成功,有错误,错误是在所有API之间共享的,因此我将创建一个可编码类来处理它,但是响应可能是不同的模型,所以下面是我要做的。

    我创建了一个一般响应类,如下所示,因此我可以将这个类用于项目中的所有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来解析响应,它将解析包含http_状态、成功、有错误、错误的“GeneralResponse”,然后response将解析所需的响应对象。

    但是在某一点上,GeneralResponse对象始终为零,并且Response对数据进行了正确的分析,我应该怎么做才能使GeneralResponse在每个API中都得到无重复的分析,因为在每个API中,我都将拥有GeneralResponse对象,所以有可能解决它吗?

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

    3 回复  |  直到 7 年前
        1
  •  1
  •   dan    7 年前

    你可以让你 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
  •   vadian    7 年前

    首先如果

    HTTP_状态、成功、有错误、错误在所有API之间共享

    为什么类属性是可选的?


    如果上述键相同,但键的值 response 是不同的用法。

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

    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
    
        3
  •  1
  •   Shehata Gamal    7 年前

    对于一个简单的案例

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

    这将解析

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