模型类,json编码和继承

时间:2018-01-02 13:13:51

标签: ios swift

我正在尝试使以下流程工作,我有很多包含不同类型请求数据的模型类,我需要根据类结构将它们编码为JSON。

我无法找到快速实现这一目标的方法。

当我将RequestType定义为一个类时,我被迫实现init(from decoder: Decoder),这对于所有平面数据模型类都是不必要的。

另一方面,当我将RequestType定义为协议时,我无法对JSONEcoder()中的变量使用request(),因为Codable不符合可编码。

// super type
protocol RequestType: Codable {

}

// model class
class InitiateSignInRequest: RequestType {
    var phone: String

    init(_ phone: String) {
        self.phone = phone
    }
}

 // a function that needs to handle all model classes
 private func request(data: RequestType, // cant use codable here... it does not conform to itself {


        let encoder = JSONEncoder()
        let encodedData = try! encoder.encode(data)
        let postPayload = String(data: encodedData, encoding: .utf8)!
        ...
        ...
        ...
    }

2 个答案:

答案 0 :(得分:1)

您可以使用ObjectMapper

  

ObjectMapper是一个用Swift编写的框架,可以轻松实现   您可以将模型对象(类和结构)转换为   JSON。

ObjectMapper使用<-运算符来定义每个成员变量与JSON之间的映射方式。

class User: Mappable {
    var username: String?
    var age: Int?
    var weight: Double!
    var array: [Any]?
    var dictionary: [String : Any] = [:]
    var bestFriend: User?                       // Nested User object
    var friends: [User]?                        // Array of Users
    var birthday: Date?

    required init?(map: Map) {

    }

    // Mappable
    func mapping(map: Map) {
        username    <- map["username"]
        age         <- map["age"]
        weight      <- map["weight"]
        array       <- map["arr"]
        dictionary  <- map["dict"]
        bestFriend  <- map["best_friend"]
        friends     <- map["friends"]
        birthday    <- (map["birthday"], DateTransform())
    }
}

答案 1 :(得分:1)

你可以这样做:

protocol RequestType: Codable {

}

extension RequestType {
    typealias T = Self
    func encode() -> Data? {
        return try? JSONEncoder().encode(self)
    }

    func decode(data: Data) -> T? {
        return try? JSONDecoder().decode(T.self, from: data)
    }
}

private func request(data: RequestType) {
    let encodedData = data.encode()!
    let postPayload = String(data: encodedData, encoding: .utf8)!

}

或者你可以像预期的那样(使用具体的类类型):

protocol RequestType: Codable {

}

class CodeableModel : RequestType {

}

// model class
class InitiateSignInRequest: CodeableModel {
    var phone: String

    init(_ phone: String) {
        self.phone = phone
        super.init()
    }

    required init(from decoder: Decoder) throws {
        fatalError("init(from:) has not been implemented")
    }
}

private func request(data: CodeableModel) {
    let encoder = JSONEncoder()
    let encodedData = try! encoder.encode(data)
    let postPayload = String(data: encodedData, encoding: .utf8)!

}