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

如何通过Swift Codable从WordPress JSON获取图片URL并加载到TableView

实现WordPress JSON图片加载到TableView的方案

没问题,我来一步步帮你搞定这个需求!首先得把你的Codable结构体补全,因为WordPress的JSON里有几个特殊键名(比如_embedded和带冒号的wp:featuredmedia)需要专门处理,然后再完成解析和图片加载的逻辑。

1. 补全所有Codable结构体

首先把缺失的结构体都补充完整,确保能正确解析JSON里的嵌套字段:

// 对应JSON里的title对象
struct Title: Codable {
    let rendered: String?
}

// 对应JSON里的content对象
struct Content: Codable {
    let rendered: String?
}

// 对应wp:featuredmedia里的单个媒体项
struct FeaturedMedia: Codable {
    let sourceUrl: String?
    
    enum CodingKeys: String, CodingKey {
        case sourceUrl = "source_url" // 映射JSON里的source_url字段
    }
}

// 对应JSON里的_embedded对象
struct Embedded: Codable {
    let wpFeaturedMedia: [FeaturedMedia]?
    
    enum CodingKeys: String, CodingKey {
        case wpFeaturedMedia = "wp:featuredmedia" // 处理带冒号的特殊键名
    }
}

// 补全你的主结构体
struct JsonSosTalleres: Codable {
    let id: Int
    let title: Title?
    let content: Content?
    let embedded: Embedded?
    
    enum CodingKeys: String, CodingKey {
        case id, title, content
        case embedded = "_embedded" // 映射JSON里的_embedded字段
    }
}

2. 解析JSON数据

假设你已经通过网络请求拿到了JSON数据,用JSONDecoder解析成[JsonSosTalleres]数组作为TableView的数据源:

// 定义数据源数组
var posts: [JsonSosTalleres] = []

// 在网络请求回调里解析数据
func fetchPosts() {
    guard let url = URL(string: "你的WordPress API接口地址") else { return }
    
    URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
        guard let data = data, error == nil else {
            print("请求失败: \(error?.localizedDescription ?? "未知错误")")
            return
        }
        
        do {
            let decoder = JSONDecoder()
            // 如果你不想手动写CodingKeys,也可以开启自动蛇形转驼峰
            // decoder.keyDecodingStrategy = .convertFromSnakeCase
            let fetchedPosts = try decoder.decode([JsonSosTalleres].self, from: data)
            DispatchQueue.main.async {
                self?.posts = fetchedPosts
                self?.tableView.reloadData()
            }
        } catch {
            print("解析失败: \(error.localizedDescription)")
        }
    }.resume()
}

3. 在TableViewCell中加载图片

首先确保你的OfertasTableViewCell里有一个UIImageView(比如叫featuredImageView),然后在tableView(_:cellForRowAt:)方法中提取图片URL并加载:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "OfertasTableViewCell", for: indexPath) as! OfertasTableViewCell
    
    let post = posts[indexPath.row]
    
    // 设置标题(可选)
    cell.titleLabel.text = post.title?.rendered
    
    // 提取图片URL并加载
    if let embedded = post.embedded,
       let mediaList = embedded.wpFeaturedMedia,
       let firstMedia = mediaList.first,
       let imageUrlString = firstMedia.sourceUrl,
       let imageUrl = URL(string: imageUrlString) {
        
        // 方式1:原生URLSession加载(需处理cell复用问题)
        cell.imageTask = URLSession.shared.dataTask(with: imageUrl) { data, _, error in
            // 排除取消的任务,避免复用错误
            guard let data = data, error == nil, (error as? URLError)?.code != .cancelled else { return }
            DispatchQueue.main.async {
                cell.featuredImageView.image = UIImage(data: data)
            }
        }.resume()
        
        // 方式2:用第三方库(推荐,自带缓存、占位图、复用处理)
        // 比如Kingfisher,先pod导入后使用:
        // cell.featuredImageView.kf.setImage(with: imageUrl, placeholder: UIImage(named: "placeholder_image"))
    } else {
        // 没有图片时显示占位图
        cell.featuredImageView.image = UIImage(named: "placeholder_image")
    }
    
    return cell
}

4. 解决Cell复用的坑

用原生URLSession加载时,要处理cell复用导致的图片错位问题。可以在OfertasTableViewCell里添加一个任务属性,在复用前取消任务:

class OfertasTableViewCell: UITableViewCell {
    @IBOutlet weak var featuredImageView: UIImageView!
    @IBOutlet weak var titleLabel: UILabel!
    
    // 保存当前图片加载任务
    var imageTask: URLSessionDataTask?
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 取消未完成的任务
        imageTask?.cancel()
        // 重置图片为占位图
        featuredImageView.image = UIImage(named: "placeholder_image")
    }
}

这样就完美解决了复用问题!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:04:10