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

Swift中如何将JSON响应转为数组?代码报错及返回类型疑问

问题分析与修复

错误根源

你遇到的Cannot assign value of type '(T.Type, Data) throws -> T' to type '[String]'错误,直接原因是这行代码完全误用了JSONDecoder:

serviceResponse = JSONDecoder.decode(loginDataModel)

JSONDecoder的decode是实例方法,不是静态方法,而且参数需要「目标类型+Data」,你已经通过try! JSONDecoder().decode(responseLogin.self,from: data)得到了解码后的loginDataModel,不需要再调用decode。

另外,你的函数返回类型是[String],但loginDataModel是responseLogin类型,两者类型不匹配,这也是核心矛盾。

修复步骤

1. 明确responseLogin结构

先确认你的responseLogin Codable结构体到底是什么样的。比如如果接口返回的是字符串数组,或者结构体里包含字符串数组字段:

// 示例1:接口直接返回[String]数组
// 不需要定义responseLogin,直接解码成[String]即可

// 示例2:接口返回包含字符串数组的结构体
struct responseLogin: Codable {
    let result: [String]
    // 可添加其他字段比如code、message等
}

2. 修正函数逻辑

下面是针对示例2的修正代码(如果是示例1,直接解码成[String].self即可):

func llamadaApiDos(postData: Data, empresa: String, boundary: String) -> [String] {
    guard let url = URL(string: "https://www.something.com") else {
        return ["无效URL"]
    }
    
    var request = URLRequest(url: url, timeoutInterval: Double.infinity)
    request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    request.httpBody = postData
    
    var serviceResponse: [String] = []
    let semaphore = DispatchSemaphore(value: 0)
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        defer { semaphore.signal() }
        
        if let error = error {
            print("请求错误: \(error)")
            return
        }
        
        guard let httpResponse = response as? HTTPURLResponse, (200..<300).contains(httpResponse.statusCode) else {
            print("状态码错误: \(httpResponse.statusCode ?? -1)")
            return
        }
        
        guard let data = data else {
            print("无返回数据")
            return
        }
        
        do {
            let loginDataModel = try JSONDecoder().decode(responseLogin.self, from: data)
            // 从解码后的模型中取出你需要的字符串数组
            serviceResponse = loginDataModel.result
        } catch {
            print("JSON解码错误: \(error)")
        }
    }
    
    task.resume()
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    
    return serviceResponse.isEmpty ? ["Error"] : serviceResponse
}

3. 关键改进点

  • 去掉了危险的try!,改用do-catch处理解码错误,避免崩溃
  • 修复了URL强制解包的问题,用guard let判断有效性
  • 直接从解码后的loginDataModel中提取需要的字符串数组,匹配[String]返回类型
  • 简化了结果判断逻辑,直接通过数组是否为空返回对应内容

关于返回类型的建议

如果你的接口返回的不是单纯的[String],而是更复杂的业务模型数组(比如用户信息数组),建议直接返回模型数组而非强行转成[String],这样后续验证逻辑更清晰:

// 假设是User模型数组
func llamadaApiDos(postData: Data, empresa: String, boundary: String) -> [User] {
    // 解码逻辑调整为try JSONDecoder().decode([User].self, from: data)
    // 返回[User]或空数组
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:30:28