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

SwiftUI调用NewsAPI后列表无数据显示,请求问题排查

SwiftUI调用NewsAPI列表无内容的排查与解决

以下是针对你遇到的问题的具体排查步骤和修复方案:

1. URL编码问题导致请求无效

搜索关键词直接拼接URL可能因特殊字符破坏地址结构,需先对关键词做URL编码:

修改NewsModel中的fetchDataFromAPI方法:

func fetchDataFromAPI() {
    let apiKey = "your_api_key"
    let searchQuery = "riciclo"
    let country = "it"
    let language = "it"
    
    // 对搜索关键词进行URL编码
    guard let encodedQuery = searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
        print("搜索关键词编码失败")
        return
    }
    
    let urlString = "https://newsapi.org/v2/top-headlines?q=\(encodedQuery)&country=\(country)&language=\(language)&apiKey=\(apiKey)"
    
    if let url = URL(string: urlString) {
        URLSession.shared.dataTask(with: url) { data, response, error in
            // ... 后续代码保持不变
        }.resume()
    }
}

2. 解码时自定义ID字段冲突

Article中自定义的id字段不存在于API响应的JSON中,明确编码键可避免潜在解码错误:

修改Article结构体:

struct Article: Identifiable, Decodable {
    var id = UUID()
    let source: Source
    let author: String?
    let title: String
    let description: String?
    let url: String
    let urlToImage: String?
    let publishedAt: String
    let content: String?
    
    // 声明编码键,排除自定义的id字段
    enum CodingKeys: String, CodingKey {
        case source, author, title, description, url, urlToImage, publishedAt, content
    }
}

3. 完善错误排查日志

当前代码缺少网络错误、HTTP响应错误的排查逻辑,添加日志可快速定位问题:

更新dataTask的闭包逻辑:

URLSession.shared.dataTask(with: url) { data, response, error in
    // 排查网络请求错误
    if let error = error {
        print("网络请求错误: \(error.localizedDescription)")
        return
    }
    
    // 排查HTTP响应状态码
    guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
        print("无效的HTTP响应: \(response.debugDescription)")
        return
    }
    
    // 解码数据
    if let data = data {
        do {
            let response = try JSONDecoder().decode(NewsResponse.self, from: data)
            DispatchQueue.main.async {
                self.articles = response.articles
                // 打印获取到的文章数量,确认是否有数据
                print("成功获取 \(response.totalResults) 篇文章")
            }
        } catch {
            print("数据解码错误: \(error)")
            // 打印原始数据,方便排查解码问题
            if let rawString = String(data: data, encoding: .utf8) {
                print("原始响应数据: \(rawString)")
            }
        }
    }
}.resume()

4. 验证API请求是否返回数据

运行代码后查看控制台日志:

  • 若打印成功获取 X 篇文章但列表为空:检查List的id参数(你用了\.url,需确保所有文章的url唯一)
  • 若打印成功获取 0 篇文章:说明API无数据返回,尝试调整搜索关键词、country或language参数
  • 若打印网络/解码错误:根据日志提示进一步排查(如API密钥是否正确、网络是否通畅)

5. 预览视图的触发问题

预览视图中可手动触发请求或调整初始化逻辑:

#Preview {
    let model = NewsModel()
    model.fetchDataFromAPI()
    return NewsListView(newsModel: model)
}

// 同时修改NewsListView的初始化方法,支持传入model:
struct NewsListView: View {
    @ObservedObject var newsModel: NewsModel
    
    init(newsModel: NewsModel = NewsModel()) {
        self.newsModel = newsModel
    }
    
    // ... 剩余代码不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:17:02