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

Swift调用MealDB API获取JSON数据失败的排查请求

MealDB iOS项目数据加载问题排查与解决方案

核心问题梳理

  • 首次基于MealDB开发iOS项目,使用JSON API始终无法加载数据
  • 更新请求逻辑后,出现错误提示:nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint
  • 对MealDB开发密钥"1"的配置存在疑惑

原代码问题分析

  1. 图片加载阻塞请求队列:原fetchDesserts函数中,循环同步下载每个餐品图片,会阻塞异步任务,导致整体请求效率极低且容易触发超时
  2. 视图生命周期调用不当:在NavigationLink的onAppear中发起请求,可能因视图跳转时机问题导致请求未正确执行
  3. 数据模型与API映射隐患:直接将idMeal转为Int,但MealDB返回的idMeal是字符串类型,可能存在转换失败的情况

更新后代码的关键问题

  1. 未处理API返回数据:在.task中调用fetchMeals后,未将返回的ApiResponse.meals赋值给desserts数组,导致视图始终无数据
  2. 错误处理过于隐蔽:仅打印URLError(.badServerResponse),未捕获并打印真实错误信息,无法定位问题根源
  3. 强制解包URL风险:使用!强制解包URL,若URL格式错误会直接崩溃
  4. 冗余的自定义解码逻辑:Meal结构体的自定义init(from decoder:)完全可以省略,CodingKeys已完成映射,自动解码即可

分步解决方案

1. 确认API密钥配置

MealDB开发环境的密钥"1"已正确集成在请求URL中(/api/json/v1/1/),无需额外配置,该URL格式符合官方要求。

2. 修复数据赋值逻辑

在.task中获取到API响应后,必须将餐品数据赋值给desserts状态变量:

.task {
    processing = true
    let response: ApiResponse? = await fetchMeals()
    // 关键:将返回的餐品数据赋值给desserts
    if let meals = response?.meals {
        self.desserts = meals
    }
    processing = false
}

3. 完善错误处理与URL安全校验

修改fetchMeals函数,添加URL校验并打印真实错误:

func fetchMeals<T: Decodable>() async -> T? {
    guard let url = URL(string: "https://themealdb.com/api/json/v1/1/filter.php?c=Dessert") else {
        print("无效的请求URL")
        return nil
    }
    
    let request = URLRequest(url: url)
    do {
        let (data, response) = try await URLSession.shared.data(for: request)
        guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
            print("服务器响应异常:\(response)")
            return nil
        }
        return try JSONDecoder().decode(T.self, from: data)
    } catch {
        // 打印真实错误,便于排查
        print("请求或解码失败:\(error)")
        return nil
    }
}

4. 简化数据模型

删除Meal结构体的自定义解码逻辑,利用自动解码:

struct Meal: Decodable, Identifiable {
    var id: String
    var name: String?
    var imgURL: String?
    
    enum CodingKeys: String, CodingKey {
        case id = "idMeal"
        case name = "strMeal"
        case imgURL = "strMealThumb"
    }
}

struct ApiResponse: Decodable {
    var meals: [Meal]?
}

5. 优化图片加载方式

不要在数据请求阶段同步下载图片,使用SwiftUI的AsyncImage异步加载图片,避免阻塞请求:

// 在DessertView的Standard View中使用AsyncImage
List(desserts) { meal in
    HStack {
        if let imgURL = meal.imgURL, let url = URL(string: imgURL) {
            AsyncImage(url: url) { image in
                image.resizable().frame(width: 50, height: 50)
            } placeholder: {
                ProgressView().frame(width: 50, height: 50)
            }
        }
        Text(meal.name ?? "Unnamed Meal")
    }
}

6. 排查网络错误提示

nw_connection_copy_connected_local_endpoint_block_invoke错误通常是网络连接层面的问题,可按以下方式排查:

  • 检查模拟器/设备的网络连接是否正常
  • 确认项目未开启网络代理,或代理配置正确
  • 尝试在浏览器中直接访问请求URL,确认API可正常返回数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:30:00