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

SwiftUI中从API获取publisherBanner图片并显示失败求助

问题排查与解决方案

以下是针对你无法从API获取并展示图片的问题,逐一排查和修改的步骤:

1. 修复数据解析的UUID冲突问题

你的PublisherBanner中id是默认生成的UUID,但默认Decodable会尝试从JSON解码该字段,而API返回的JSON通常不会包含id键,这会直接导致解析失败,拿不到数据。

修改PublisherBanner结构,通过CodingKeys忽略id字段:

public struct PublisherBanner: Decodable, Hashable {
    public var id = UUID()
    public let url: String
    
    // 仅解码url字段,忽略id
    enum CodingKeys: String, CodingKey {
        case url
    }
    
    public init(url: String) {
        self.url = url
    }
}

2. 匹配API返回的JSON格式

确保API返回的JSON结构与Banner模型完全对应,正确格式示例:

{
  "publisherBanners": [
    {"url": "https://example.com/banner1.jpg"},
    {"url": "https://example.com/banner2.jpg"}
  ]
}

如果API返回的是下划线命名的键(如publisher_banners),需要给JSONDecoder添加键转换策略:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let results = try decoder.decode(Banner.self, from: data)

3. 验证URL有效性

  • 将视图模型中的let url = "apiUrlExample"替换为真实可用的API地址,确保该地址能正常返回JSON数据。
  • 检查item.url是否为完整的HTTP/HTTPS链接,如果是相对路径(如/images/banner.jpg),需要拼接API基础域名:
let baseDomain = "https://your-api-domain.com"
AsyncImage(url: URL(string: baseDomain + item.url)) { ... }

4. 完善错误排查逻辑

在视图模型的getData方法中添加详细错误打印,方便定位问题:

func getData(url: String) {
    guard let url = URL(string: url) else { 
        print("无效的API地址")
        return 
    }
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let error = error {
            print("网络请求错误: \(error.localizedDescription)")
            return
        }
        // 检查响应状态码是否正常
        guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
            print("API返回错误状态码: \(response as? HTTPURLResponse ?? HTTPURLResponse()).statusCode)")
            return
        }
        if let data = data {
            do {
                let decoder = JSONDecoder()
                // 如需下划线转驼峰则取消注释
                // decoder.keyDecodingStrategy = .convertFromSnakeCase
                let results = try decoder.decode(Banner.self, from: data)
                DispatchQueue.main.async {
                    self.datas = results.publisherBanners
                }
            } catch {
                print("解析错误: \(error)")
                // 打印原始JSON数据,方便排查格式问题
                if let jsonString = String(data: data, encoding: .utf8) {
                    print("API返回原始数据: \(jsonString)")
                }
            }
        }
    }.resume()
}

5. 优化AsyncImage的使用

确保图片加载时比例正确,避免拉伸变形:

AsyncImage(url: URL(string: item.url)) { image in
    image
        .resizable()
        .padding(4)
        .frame(width: 150, height: 215)
        .scaledToFit()
} placeholder: {
    Image("logo_gray")
        .resizable()
        .padding(1)
        .frame(width: 150, height: 215)
        .scaledToFit()
}

按上述步骤逐一排查修改,即可解决图片加载失败的问题。

内容的提问来源于stack exchange,提问作者Anup Kumar Mishra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:55:21