将JSON字典嵌入密钥中?

问题描述 投票:1回答:1

我需要在密钥内发送一个请求,期望它看起来像这样:

 {
  "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: [])

我确定解决方案很简单,但我不能让它工作!非常感谢

ios json swift alamofire codable
1个回答
2
投票

JSONSerialization

JSONSerialization仅适用于数组,字典,字符串,数字等简单类型。

如果你想使用它,那么你不需要Codable,而你需要函数func toDict() -> [String: Any],它将你的UserSignupRequest转换为字典。 然后你的开关将如下所示:

case .signup(let request):
    return ["user": request.toDict()]
}

JSONEncoder

JSONSerialization是旧api,如果你打算使用Codable,你需要使用:

urlRequest.httpBody = try JSONEncoder().encode(parameters)

Generic parameter 'T' could not be inferred

我假设你得到的参数如下:

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())
© www.soinside.com 2019 - 2024. All rights reserved.