Swift调用The Movie DB API返回混合类型数组如何适配Identifiable渲染
最优处理方案
你最初定义枚举区分类型的思路是完全正确的,不需要更换实现方向,只需要补全枚举的Decodable逻辑、加上Identifiable协议遵循即可解决问题,你之前注释掉的id计算属性本身是可用的。
完整实现步骤
- 补全枚举的解码逻辑:The Movie DB的多类型搜索接口返回的每个结果条目都带有
media_type字段,取值为movie/tv/person分别对应电影、剧集、演员,你可以根据这个字段手动实现枚举的解码逻辑。 - 给枚举加上
Identifiable协议遵循,复用你之前写的id计算属性,即可满足列表渲染的协议要求。
完整代码示例
// 假设你的Movie、Show、Person结构体已经提前实现了Decodable、Identifiable协议 struct MultiSearchResults: Decodable { let page: Int let results: [Result] let total_results: Int let total_pages: Int enum Result: Decodable, Identifiable { case movie(Movie) case show(Show) case person(Person) var id: Int { switch self { case .movie(let movie): return movie.id case .show(let show): return show.id case .person(let person): return person.id } } // 手动实现解码逻辑 enum CodingKeys: String, CodingKey { case mediaType = "media_type" } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let mediaType = try container.decode(String.self, forKey: .mediaType) let singleValueContainer = try decoder.singleValueContainer() switch mediaType { case "movie": self = .movie(try singleValueContainer.decode(Movie.self)) case "tv": self = .show(try singleValueContainer.decode(Show.self)) case "person": self = .person(try singleValueContainer.decode(Person.self)) default: throw DecodingError.dataCorruptedError( forKey: .mediaType, in: container, debugDescription: "未知媒体类型: \(mediaType)" ) } } } }
列表渲染用法
实现后你可以直接遍历混合类型的结果数组,同时支持根据不同类型渲染不同的视图样式,比拆分数组更加灵活:
List { ForEach(searchResults.results) { result in switch result { case .movie(let movie): // 渲染电影条目视图 MovieItemView(movie: movie) case .show(let show): // 渲染剧集条目视图 ShowItemView(show: show) case .person(let person): // 渲染演员条目视图 PersonItemView(person: person) } } }
你的备选方案适用场景
- 拆分三个独立数组:适合需要分标签/分栏单独展示不同类型结果的场景,可以通过
compactMap快速过滤得到对应类型的数组,不需要修改现有结构:// 过滤得到所有电影结果 let movies = searchResults.results.compactMap { result -> Movie? in guard case .movie(let movie) = result else { return nil } return movie } // 剧集、演员数组的过滤逻辑同理 - 不遵循Identifiable渲染:完全没必要,即使不用Identifiable你也需要给ForEach指定唯一标识字段,实现成本更高,代码可读性也更低。
内容的提问来源于stack exchange,提问作者Damian Kociszewski
相关产品推荐
相关产品推荐

