调用GET API获取数据后[user]数组无法填充的问题求助
解决API数据解码后无法填充数组的问题
问题分析
你的代码能获取到API响应数据,但userdata数组始终为空,核心原因大概率是模型类不符合Codable要求、解码错误未排查,或者TableView代理未正确设置。
具体修复步骤
1. 修正模型类(必须遵循Codable)
首先,你的user结构体/类必须遵循Codable协议,且属性要和JSONPlaceholder返回的todos字段完全匹配(字段名、类型一致)。另外Swift类型名规范为首字母大写,建议改成User:
struct User: Codable { let userId: Int let id: Int let title: String let completed: Bool }
之后把代码里所有的[user]替换成[User],包括userdata的声明:
var userdata = [User]() { didSet { DispatchQueue.main.async { [self] in tableView.reloadData() } } }
2. 打印详细解码错误
原代码只打印"error"无法定位具体问题,修改解码部分的错误处理,打印完整错误信息:
do { let decodedData = try decoder.decode([User].self, from: data) self.userdata = decodedData print("解码成功,共\(decodedData.count)条数据") // 验证解码结果 } catch { print("解码失败:\(error.localizedDescription)") print("错误详情:\(error)") // 精准定位问题 }
3. 正确设置TableView代理
你注释掉了tableView.dataSource = self和tableView.delegate = self,要么取消注释:
override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self // ... 其他代码 }
要么在Storyboard中,把TableView的dataSource和delegate拖拽关联到ViewController上,否则TableView不会调用数据源方法,即使数组有数据也不会显示。
4. 验证API返回数据匹配
你调用的https://jsonplaceholder.typicode.com/todos返回的每条数据结构是:
{ "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false }
确保你的User模型属性和这些字段完全对应,若字段名不一致可通过CodingKeys映射。
修复后的完整ViewController代码示例
import UIKit struct User: Codable { let userId: Int let id: Int let title: String let completed: Bool } class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var userdata = [User]() { didSet { DispatchQueue.main.async { [self] in tableView.reloadData() } } } @IBOutlet var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self let movieManager = MovieManager() movieManager.fetchMovies { data in let decoder = JSONDecoder() do { let decodedData = try decoder.decode([User].self, from: data) self.userdata = decodedData print("解码成功:\(decodedData.count)条数据") } catch { print("解码失败:\(error.localizedDescription)") print("错误详情:\(error)") } } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return userdata.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = userdata[indexPath.row].title return cell } }
内容的提问来源于stack exchange,提问作者Utsav Gabani
相关产品推荐
相关产品推荐

