Swift调用自定义Django API返回空列表问题求助
问题排查与解决方案
1. 先捕获解码错误,明确问题根源
你的代码用try?解码会静默忽略错误,导致你无法知晓解码失败的具体原因。替换为try并打印错误信息:
do { let (data, response) = try await URLSession.shared.data(from: url) // 打印API返回的原始JSON内容,方便排查结构问题 if let jsonString = String(data: data, encoding: .utf8) { print("API返回内容:\(jsonString)") } let decodedResponse = try JSONDecoder().decode([Entree].self, from: data) entrees = decodedResponse } catch { print("解码失败详情:\(error)") }
2. 适配Django API的默认返回结构
Django REST Framework的列表接口默认返回包含results字段的对象,而非直接的数组,格式示例:
{ "count": 3, "next": null, "previous": null, "results": [ {"id": 1, "menu": "午餐", "name": "宫保鸡丁", "description": "经典川菜"}, ... ] }
此时需新增一个结构体适配该结构:
struct EntreeListResponse: Codable { let results: [Entree] }
解码时改为:
let decodedResponse = try JSONDecoder().decode(EntreeListResponse.self, from: data) entrees = decodedResponse.results
3. 修正字段拼写错误
你的Entree结构体中descripton拼写错误(少了一个i),如果Django模型中字段名为description,会导致解码失败。修正为:
struct Entree: Codable { var id: Int var menu: String var name: String var description: String // 修正拼写 }
4. 确保请求获取JSON格式响应
在请求中明确设置Accept头,强制Django返回JSON格式:
var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Accept") let (data, response) = try await URLSession.shared.data(for: request)
5. 修复模拟器与主机的网络连通性
模拟器中的127.0.0.1指向模拟器自身,而非你的电脑主机。需替换为电脑的局域网IP(如192.168.1.105),或使用iOS模拟器专属的主机地址http://host.docker.internal:8000(若Django运行在Docker中),示例:
guard let url = URL(string: "http://192.168.1.105:8000/api/main_course/?format=json") else { print("URL Invalid") return }
内容的提问来源于stack exchange,提问作者JimmyFl0
相关产品推荐
相关产品推荐

