如何在Alamofire中以对象而非Parameter形式发送数据?
解决Alamofire发送JSON时的
Invalid type in JSON write (_SwiftValue)错误 这个报错我之前也踩过坑,本质是Alamofire无法序列化你传入的自定义类型或非JSON兼容值——并不是它不接受字典数组格式的city字段,你想要的{"city": [{"name": "...", ...}, ...]}完全是合法的JSON结构,问题出在你传递的参数值类型上。
先搞清楚错误根源
Invalid type in JSON write (_SwiftValue) 提示说明你在Parameters里混入了Swift无法自动转成JSON的类型,常见场景包括:
- 自定义的结构体/类(比如你封装的
City模型,没实现序列化逻辑) - 未拆包的Optional值
- 非JSON标准类型(比如自定义枚举、未转换格式的Date类型)
解决方案分两种场景:
场景1:用Alamofire的Parameters字典发送
如果还是想通过Parameters传递参数,要确保所有值都是JSON可序列化的基础类型:
- 把自定义模型转成字典
假设你有一个City结构体:
struct City { let name: String let address: String let lat: Double }
给它加个转字典的扩展,把模型转成基础类型字典:
extension City { func asDictionary() -> [String: Any] { return [ "name": name, "address": address, "lat": lat ] } }
- 构建合法的Parameters
把你的City数组转成字典数组,再塞进Parameters:
// 假设你有两个City实例 let city1 = City(name: "Beijing", address: "XXX Street", lat: 39.9042) let city2 = City(name: "Shanghai", address: "YYY Road", lat: 31.2304) let cityDicts = [city1.asDictionary(), city2.asDictionary()] let parameters: Parameters = [ "userName": yourUsername, "password": yourPassword, "city": cityDicts // 这里是字典数组,完全符合接口要求 ]
- 处理Optional值
如果lat是Optional类型(比如Double?),一定要确保它有值,或者给个默认值避免nil:
"lat": lat ?? 0.0 // 防止传入nil导致序列化失败
场景2:手动序列化JSON Data发送(更稳妥)
如果上面的方法还是有问题,直接把整个请求模型转成JSON Data,绕开Alamofire的参数序列化:
- 定义请求模型并遵循Codable
struct LoginRequest: Codable { let userName: String let password: String let city: [City] } // 让City也遵循Codable,自动支持序列化 struct City: Codable { let name: String let address: String let lat: Double }
- 编码成JSON Data并发送
let requestModel = LoginRequest( userName: yourUsername, password: yourPassword, city: [city1, city2] ) do { let jsonData = try JSONEncoder().encode(requestModel) AF.request("你的接口URL", method: .post, headers: ["Content-Type": "application/json"]) .httpBody(jsonData) .responseJSON { response in // 处理你的响应逻辑 switch response.result { case .success(let value): print("请求成功:\(value)") case .failure(let error): print("请求失败:\(error)") } } } catch { print("JSON编码失败:\(error.localizedDescription)") }
最后排查小细节
- 确认
username、password都是非Optional的基础类型(String) - 如果用到Date类型,记得在
JSONEncoder里设置日期编码策略,比如.iso8601
内容的提问来源于stack exchange,提问作者Nadia
相关产品推荐
相关产品推荐

