JSONSerialization
JSONSerialization
работает только с простыми типами, такими как массивы, словари, строки, числа и т. Д.
Если вы хотите использовать его, то вам не нужно Codable
вместо этого вам нужна функция func toDict() -> [String: Any]
, которая преобразует ваш UserSignupRequest
в словарь.
Тогда ваш переключатель будет выглядеть следующим образом:
case .signup(let request):
return ["user": request.toDict()]
}
JSONEncoder
JSONSerialization
isстарый API, и если вы планируете использовать Codable
, вам нужно использовать:
urlRequest.httpBody = try JSONEncoder().encode(parameters)
Общий параметр 'T' не может быть выведен
Я предполагаю, что вы получаете такие параметры, как:
func parameters(for request: RequestType) -> [String: Any] {
switch request {
case .signup(let request):
return ["user": request]
}
}
Поэтому, когда вы передаете свои параметры в кодировщик, он не знает, какой тип кодировать.
Чтобы решить, мы можем вернуть не просто словарь, а конкретный протокол / тип aka:
protocol Request {
func encode(by encoder: JSONEncoder) throws -> Data
}
extension Request where Self: Encodable {
func encode(by encoder: JSONEncoder) throws -> Data {
/// since it will be method on specific type, JSONEncoder will know what type is encoding
return try encoder.encode(self)
}
}
struct UserSignupRequest: Codable, Request {
struct RequestData: Codable {
let email: String
let password: String
}
let data: RequestData
enum CodingKeys: String, CodingKey {
case data = "user"
}
}
func parameters(for request: RequestType) -> Request {
switch request {
case .signup(let requestData):
return UserSignupRequest(data: requestData)
}
}
Так что теперь вы можете сделать
urlRequest.httpBody = try parameters.encode(by: JSONEncoder())