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

Swift 5中用URLSession发送数组开头的POST请求遇阻求助

问题解决:Swift发送数组开头的POST请求报错

核心问题排查

你的代码存在几个明确的错误点,直接导致请求或解码失败:

  • 模型与接口返回不匹配:接口返回的pageno是字符串类型(如"1"),但你在DocumentStruct里定义为Int,JSONDecoder无法自动完成字符串到整数的转换,会抛出解码错误。
  • 无效属性访问:最后打印的json.document.records[0].car_marka,但RecordStruct中根本没有这个属性,会触发运行时错误。
  • 请求体格式问题:使用.prettyPrinted生成的JSON带有换行和缩进,部分服务器无法正确解析这类格式化后的请求体。

修正后的完整代码

private func getDataCars() {
    // 修正模型,完全匹配接口返回的字段类型与内容
    struct Result: Codable {
        let status: String
        let code: Int
        let message: String
        let document: DocumentStruct
    }
    
    struct DocumentStruct: Codable {
        let pageno: String
        let pagesize: String
        let total_count: String
        let records: [RecordStruct]
    }
    
    struct RecordStruct: Codable {
        let user_id: String
        let user_name: String
        let user_mail: String
        let user_password: String
        let user_phone: String
        let user_durum: String
    }
    
    let parameters = [["columnName": "nameofcolumn", "columnLogic": "LIKE", "columnValue": "searchstring"]]
    guard let url = URL(string: "http://getapiadress") else {
        print("无效的接口URL")
        return
    }
    let authTokenString = "somekey"
    let session = URLSession.shared
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("Bearer \(authTokenString)", forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    
    do {
        // 使用默认序列化选项,生成紧凑格式的JSON请求体
        request.httpBody = try JSONSerialization.data(withJSONObject: parameters)
    } catch {
        print("请求体序列化失败:\(error.localizedDescription)")
        return
    }
    
    let task = session.dataTask(with: request) { data, response, error in
        // 处理网络层错误
        if let error = error {
            print("网络请求错误:\(error.localizedDescription)")
            return
        }
        
        // 检查服务器响应状态码
        if let httpResponse = response as? HTTPURLResponse {
            print("响应状态码:\(httpResponse.statusCode)")
            if httpResponse.statusCode < 200 || httpResponse.statusCode >= 300 {
                print("服务器返回错误状态码")
                // 打印服务器返回的错误内容,方便排查
                if let data = data, let errorContent = String(data: data, encoding: .utf8) {
                    print("服务器错误详情:\(errorContent)")
                }
                return
            }
        }
        
        guard let data = data else {
            print("未获取到响应数据")
            return
        }
        
        // 打印原始响应数据,辅助排查解码问题
        if let rawResponse = String(data: data, encoding: .utf8) {
            print("原始响应内容:\(rawResponse)")
        }
        
        do {
            let result = try JSONDecoder().decode(Result.self, from: data)
            print("请求成功")
            // 访问模型中存在的属性
            if let firstUser = result.document.records.first {
                print("第一个用户:\(firstUser.user_name)")
            }
        } catch {
            print("数据解码失败:\(error)")
            // 打印解码错误的详细信息
            if let decodeError = error as? DecodingError {
                print("解码错误详情:\(decodeError)")
            }
        }
    }
    task.resume()
}

关键修正说明

  1. 模型字段完全匹配:将pageno改为String类型,补充接口返回的code、message、pagesize字段,确保解码时不会因为字段类型或缺失报错。
  2. 修复无效属性访问:将不存在的car_marka替换为模型中实际存在的user_name。
  3. 优化请求体序列化:移除.prettyPrinted选项,生成服务器易解析的紧凑JSON格式。
  4. 增强错误排查能力:添加URL有效性检查、状态码校验、原始响应打印,方便快速定位问题。

内容的提问来源于stack exchange,提问作者Ali KAYA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:35:21