Swift使用Alamofire请求后DispatchQueue闭包未运行、视图无数据加载问题
问题排查与解决方案
根因定位
- 核心问题出在JSON解析逻辑:你的
Recipe、Ingredient结构体遵循Decodable协议时,默认会尝试解析所有存储属性,而你本地定义的id属性是自动生成的UUID,接口返回的JSON数据中没有对应id字段,导致解析直接失败。 - 你使用
try?进行解析操作,解析失败时会直接返回nil,所有错误信息被静默吞掉,无法定位问题,所以你看不到解析环节的报错,也走不到后续DispatchQueue的赋值逻辑。 - 额外可能问题:你使用HTTP协议请求本地接口,iOS默认的应用传输安全(ATS)规则会拦截未配置信任的HTTP请求,也可能导致请求异常。
修复步骤
1. 给模型添加CodingKeys排除id字段
在两个模型中显式指定需要解析的字段,排除本地生成的id:
struct Recipe: Decodable, Identifiable { var id = UUID() var name: String var image: String var spirit: String var ice: String var glass: String var yield: String var description: String var ingredients: [Ingredient] // 仅枚举JSON中存在的字段,id不需要参与解析 enum CodingKeys: String, CodingKey { case name, image, spirit, ice, glass, yield, description, ingredients } } struct Ingredient: Decodable, Identifiable { var id = UUID() var bottle: String var amount: String enum CodingKeys: String, CodingKey { case bottle, amount } }
2. 替换try?为do-catch捕获错误
修改请求逻辑,显式捕获解析错误方便调试:
AF.request("http://localhost:3000/recipes").responseData { response in guard let data = response.data else { print("请求无返回数据") return } do { let decodedRecipes = try JSONDecoder().decode([Recipe].self, from: data) DispatchQueue.main.async { self.recipes = decodedRecipes print("解析成功,共\(decodedRecipes.count)条数据") } } catch { // 这里会打印具体的解析错误,比如字段缺失、类型不匹配等 print("解析失败错误:\(error.localizedDescription)") print("详细错误信息:\(error)") } }
你也可以直接使用Alamofire自带的responseDecodable简化代码:
AF.request("http://localhost:3000/recipes").responseDecodable(of: [Recipe].self) { response in switch response.result { case .success(let recipes): DispatchQueue.main.async { self.recipes = recipes } case .failure(let error): print("请求或解析失败:\(error)") } }
3. 配置HTTP请求权限(可选)
如果请求被ATS拦截,可以在项目的Info.plist中添加本地接口的HTTP信任配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>localhost</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
通用调试建议
- 涉及
Decodable解析的场景不要使用try?,必须显式捕获错误,Swift的DecodingError会明确告知缺失字段、类型不匹配等具体问题,定位效率极高。 - 遇到解析异常时可以先把返回的
data转成String打印,确认返回的JSON结构和预期一致,排除服务端返回异常的情况。
内容的提问来源于stack exchange,提问作者user11371080
相关产品推荐
相关产品推荐

