Swift 3:HTTP请求提交单个对象参数的方法及400错误解决
在Swift 3中用原生网络库提交单个对象作为HTTP请求参数的解决方案
你遇到的400错误核心原因是直接把自定义的GoogleMap对象传给了JSONSerialization.data(withJSONObject:)——这个API只能序列化Foundation自带的类型(比如[String: Any]字典、Array数组这类),没办法直接处理自定义类/结构体。下面是具体的解决办法:
步骤1:让自定义对象支持JSON编码
在Swift 3中,你需要让GoogleMap类/结构体遵守Encodable协议(如果需要解码响应的话再加Decodable),并手动实现编码逻辑:
// 假设你的GoogleMap类结构如下,根据实际属性调整 class GoogleMap: Encodable { var latitude: Double var longitude: Double var address: String? init(latitude: Double, longitude: Double, address: String?) { self.latitude = latitude self.longitude = longitude self.address = address } // Swift 3需要手动实现编码方法(Swift 4+可自动合成) func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) try container.encodeIfPresent(address, forKey: .address) } // 定义编码键值,必须和后端接口要求的字段名完全匹配! enum CodingKeys: String, CodingKey { case latitude = "lat" case longitude = "lng" case address } }
步骤2:修正请求代码逻辑
你原来的代码存在重复设置httpMethod的问题,且生成请求体的方式错误,修正后的完整代码如下:
guard let url = URL(string: "http://test.com/google/getAddress") else { print("无效的URL地址") return } // 初始化你的参数对象 let parameters = GoogleMap(latitude: 39.9042, longitude: 116.4074, address: "北京市") var request = URLRequest(url: url) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") // 建议添加,告知服务器我们接受JSON格式响应 // 用JSONEncoder将自定义对象转为Data(Swift 3开始原生支持) do { let httpBody = try JSONEncoder().encode(parameters) request.httpBody = httpBody } catch { print("参数编码失败:\(error.localizedDescription)") return } // 发起请求并处理响应 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("请求发生错误:\(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse else { print("无效的响应格式") return } if httpResponse.statusCode == 200 { // 处理成功响应 if let data = data { do { let responseJSON = try JSONSerialization.jsonObject(with: data, options: []) print("接口响应:\(responseJSON)") } catch { print("响应解析失败:\(error.localizedDescription)") } } } else { print("请求失败,状态码:\(httpResponse.statusCode)") // 可打印后端返回的错误信息辅助排查 if let data = data, let errorMsg = String(data: data, encoding: .utf8) { print("服务器返回错误信息:\(errorMsg)") } } } task.resume()
额外排查点
如果仍然出现400错误,可以从以下方向检查:
- 确认
GoogleMap的CodingKeys和后端接口要求的字段名、大小写完全一致(多数后端接口对大小写敏感) - 检查参数值是否符合后端的校验规则(比如是否有必填字段未赋值)
- 可以用Postman等工具,将生成的JSON参数直接发送请求测试,排除代码外的接口问题
内容的提问来源于stack exchange,提问作者Ryan110
相关产品推荐
相关产品推荐

