如何通过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
相关产品推荐
相关产品推荐

