如何将遵循Codable的结构体编码为Alamofire POST请求参数 - Swift
错误根源
你当前的报错核心是重复编码:你先手动用JSONEncoder把APIAccountID实例转成了Data,之后又把这个Data传给JSONParameterEncoder做了二次编码,最终发送给后端的内容是被包了一层的字符串,不是预期的用户名字典结构,所以Django才会返回Expected a dictionary, but got str的错误。
正确实现方案
Alamofire的JSONParameterEncoder、URLEncodedFormParameterEncoder本身就支持直接传入遵循Encodable协议的对象,不需要提前手动转Data,按如下方式调整代码即可:
第一步:调整parameters属性定义
把返回类型从Data?改为(any Encodable)?,直接返回遵循Codable的实例:
var parameters: (any Encodable)? { switch self { case .fetchAccessToken(let accountID): // 直接返回Codable实例,不需要手动编码为Data return accountID // 其他接口的Codable参数也直接返回对应实例即可 default: return nil } }
第二步:优化URLRequestConvertible实现
不需要额外修改编码逻辑,Alamofire的编码器会自动处理Encodable对象:
// MARK: - URLRequestConvertible extension APIRouter: URLRequestConvertible { func asURLRequest() throws -> URLRequest { let url = try baseURL.asURL().appendingPathComponent(path) var request = URLRequest(url: url) request.method = method // 统一放在外层设置Accept头即可 request.setValue("application/json", forHTTPHeaderField: "Accept") guard let parameters = parameters else { return request } if method == .get { request = try URLEncodedFormParameterEncoder().encode(parameters, into: request) } else if method == .post { request = try JSONParameterEncoder().encode(parameters, into: request) } return request } }
调整完成后Django端通过request.data就能直接拿到username、password字段,不会再报类型错误。
内容的提问来源于stack exchange,提问作者Paul Bénateau
相关产品推荐
相关产品推荐

