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
相关产品推荐
相关产品推荐

