You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将遵循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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:45:04