我正在尝试使以下流程工作,我有很多包含不同类型请求数据的模型类,我需要根据类结构将它们编码为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)!
...
...
...
}
答案 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)!
}