我需要在密钥内发送请求,希望它看起来像这样:
{
"user": {
"email": String,
"password": String
}
}
我正在尝试通过创建具有电子邮件和密码属性并符合编码的UserSignupRequest
来做到这一点:
struct UserSignupRequest: Codable {
let email: String
let password: String
enum CodingKeys: String, CodingKey {
case email
case password
}
}
然后通过以下方式为alamofire创建参数:
case .signup(let request):
return ["user": request]
}
我的逻辑是,这将在用户父键内创建子键值对,但是我的应用出现致命错误,并尝试时出现错误:
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
我确定解决方案很简单,但我无法完全解决这个问题!非常感谢
答案 0 :(得分:2)
JSONSerialization
仅适用于简单类型,例如数组,字典,字符串,数字等。
如果要使用它,则不需要Codable
,而需要将func toDict() -> [String: Any]
转换为字典的函数UserSignupRequest
。
然后您的开关将如下所示:
case .signup(let request):
return ["user": request.toDict()]
}
JSONSerialization
是旧的api,如果您打算使用Codable
,则需要使用:
urlRequest.httpBody = try JSONEncoder().encode(parameters)
我假设您得到的参数如下:
func parameters(for request: RequestType) -> [String: Any] {
switch request {
case .signup(let request):
return ["user": request]
}
}
因此,当您在编码器中传递参数时,他不知道要编码哪种类型。
要解决此问题,我们不仅可以返回字典,还可以返回特定的协议/类型:
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())