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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:46:12