Swift Decodable问题:无法将RecentTvListDays赋值给[TvShowDetails]?
解决类型不匹配错误:Cannot assign value of type 'RecentTvListDays' to type '[TvShowDetails]?'
咱先把问题拆明白:你声明的tvShows是[TvShowDetails]?类型(可选的剧集详情数组),但你试图赋值的shows.data是RecentTvListDays类型的对象——这俩完全不是一个“品类”的东西,编译器当然会报错啦。
问题根源
从错误和你提到的JSON结构来看,API返回的数据应该是外层包裹了一个按天分组的容器对象(也就是RecentTvListDays),而你需要的[TvShowDetails]数组是这个容器对象里的某个子属性,不是直接等于整个容器本身。
一步步解决
1. 先确认你的模型结构是否正确
假设你的JSON结构大概是这样(对应RecentTvListDays):
{ "days": [ { "date": "2024-05-20", "tvShows": [/* 这里才是你要的[TvShowDetails]数组 */] } ] }
那你的RecentTvListDays模型应该定义成这样(以Codable为例):
struct RecentTvListDays: Codable { let days: [TvDay] // 按天分组的数组 } struct TvDay: Codable { let date: String let tvShows: [TvShowDetails] // 这才是你需要的剧集列表 } struct TvShowDetails: Codable { // 这里放剧集的具体属性,比如id、name、posterUrl等 let id: Int let name: String // ...其他属性 }
2. 修正赋值逻辑
不要直接把整个RecentTvListDays对象赋值给tvShows,而是提取里面的目标数组:
func fetchTvItems() { let jsonUrlString = "https://www.what-song.com/api/air-episodes" guard let url = URL(string: jsonUrlString) else { return } URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, error == nil else { return } do { let shows = try JSONDecoder().decode(RecentTvListDays.self, from: data) // 提取你需要的剧集数组——这里假设取第一天的剧集,根据你的需求调整 if let firstDayShows = shows.days.first?.tvShows { DispatchQueue.main.async { self.tvShows = firstDayShows self.collectionView.reloadData() // 别忘了刷新UI } } } catch { print("解析错误:\(error)") } }.resume() }
3. 排查小技巧
- 打印
shows.data的类型和内容,确认结构:print(type(of: shows.data)) // 看它到底是什么类型 dump(shows.data) // 打印完整的对象结构,找到你要的数组在哪里 - 核对JSON的key和模型属性名是否一致,如果不一致,要在模型里添加
CodingKeys来映射:struct TvDay: Codable { let date: String let tvShows: [TvShowDetails] enum CodingKeys: String, CodingKey { case date case tvShows = "tv_shows" // 如果JSON里是下划线命名的话 } }
内容的提问来源于stack exchange,提问作者unicorn_surprise
相关产品推荐
相关产品推荐

