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

Swift开发报错:类型'[ListB]'无'books'成员问题求助

问题解决:Value of type '[ListB]' has no member 'books'

问题场景

执行fetchAPIDataTop100FHC函数时,在books = hardfictList.books行报错:Value of type '[ListB]' has no member 'books'。相关代码如下:

报错函数代码

func fetchAPIDataTop100FHC() {
        
        let url = myUrl
              AF.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil)
                .response{ resp in
                    switch resp.result{
                    case .success(let data):
                        do{
                            let jsonData = try JSONDecoder().decode(NYTTop100FictionModel.self, from: data!)
                             let hardfictList = jsonData.results.listsb.filter ({ $0.listNameEncoded == "hardcover-fiction" })
                            //print(jsonData.results.listsb)
                            books = hardfictList.books
                        } catch {
                            print(String(describing: error))
                        }
                    case .failure(let error):
                        print(String(describing: error))
                    }
                } //end response

        } //end fetch API

相关结构体代码

struct Result: Decodable {
  let bestsellersDate: String
  let publishedDate: String
  let publishedDateDescription: String
  let previousPublishedDate: String
  let nextPublishedDate: String
  let listsb: [ListB]

  private enum CodingKeys: String, CodingKey {
    case bestsellersDate = "bestsellers_date"
    case publishedDate = "published_date"
    case publishedDateDescription = "published_date_description"
    case previousPublishedDate = "previous_published_date"
    case nextPublishedDate = "next_published_date"
    case listsb = "lists"
  }

  init(bestsellersDate: String, publishedDate: String, publishedDateDescription: String, previousPublishedDate: String, nextPublishedDate: String, listsb: [ListB]) {
    self.bestsellersDate = bestsellersDate
    self.publishedDate = publishedDate
    self.publishedDateDescription = publishedDateDescription
    self.previousPublishedDate = previousPublishedDate
    self.nextPublishedDate = nextPublishedDate
    self.listsb = listsb
  }
}

struct ListB: Decodable {
  let listID: Int
  let listName: String
  let listNameEncoded: String
  let displayName: String
  let updated: String
  let books: [Book]

  private enum CodingKeys: String, CodingKey {
    case listID = "list_id"
    case listName = "list_name"
    case listNameEncoded = "list_name_encoded"
    case displayName = "display_name"
    case updated
    case books
  }

    init(listID: Int, listName: String, listNameEncoded: String, displayName: String, updated: String, books: [Book]) {
    self.listID = listID
    self.listName = listName
    self.listNameEncoded = listNameEncoded
    self.displayName = displayName
    self.updated = updated
    self.books = books
  }
}

struct Book: Codable, Identifiable {
    let id = UUID()
  let ageGroup: String
  let amazonProductURL: URL
  let articleChapterLink: String
  let author: String
  let bookImage: URL?
  let bookImageWidth: Int?
  let bookImageHeight: Int?
  let bookReviewLink: String
  let bookUri: URL
  let btrn: String
  let contributor: String
  let contributorNote: String
  let createdDate: String
  let description: String
  let firstChapterLink: String
  let price: String
  let primaryIsbn10: String
  let primaryIsbn13: String
  let publisher: String
  let rank: Int
  let rankLastWeek: Int
  let sundayReviewLink: String
  let title: String
  let updatedDate: String
  let weeksOnList: Int
  let buyLinks: [BuyLink]

  private enum CodingKeys: String, CodingKey {
    case ageGroup = "age_group"
    case amazonProductURL = "amazon_product_url"
    case articleChapterLink = "article_chapter_link"
    case author
    case bookImage = "book_image"
    case bookImageWidth = "book_image_width"
    case bookImageHeight = "book_image_height"
    case bookReviewLink = "book_review_link"
    case bookUri = "book_uri"
    case btrn
    case contributor
    case contributorNote = "contributor_note"
    case createdDate = "created_date"
    case description
    case firstChapterLink = "first_chapter_link"
    case price
    case primaryIsbn10 = "primary_isbn10"
    case primaryIsbn13 = "primary_isbn13"
    case publisher
    case rank
    case rankLastWeek = "rank_last_week"
    case sundayReviewLink = "sunday_review_link"
    case title
    case updatedDate = "updated_date"
    case weeksOnList = "weeks_on_list"
    case buyLinks = "buy_links"
  }

  init(ageGroup: String, amazonProductURL: URL, articleChapterLink: String, author: String, bookImage: URL?, bookImageWidth: Int?, bookImageHeight: Int?, bookReviewLink: String, bookUri: URL, btrn: String, contributor: String, contributorNote: String, createdDate: String, description: String, firstChapterLink: String, price: String, primaryIsbn10: String, primaryIsbn13: String, publisher: String, rank: Int, rankLastWeek: Int, sundayReviewLink: String, title: String, updatedDate: String, weeksOnList: Int, buyLinks: [BuyLink]) {
    self.ageGroup = ageGroup
    self.amazonProductURL = amazonProductURL
    self.articleChapterLink = articleChapterLink
    self.author = author
    self.bookImage = bookImage
    self.bookImageWidth = bookImageWidth
    self.bookImageHeight = bookImageHeight
    self.bookReviewLink = bookReviewLink
    self.bookUri = bookUri
    self.btrn = btrn
    self.contributor = contributor
    self.contributorNote = contributorNote
    self.createdDate = createdDate
    self.description = description
    self.firstChapterLink = firstChapterLink
    self.price = price
    self.primaryIsbn10 = primaryIsbn10
    self.primaryIsbn13 = primaryIsbn13
    self.publisher = publisher
    self.rank = rank
    self.rankLastWeek = rankLastWeek
    self.sundayReviewLink = sundayReviewLink
    self.title = title
    self.updatedDate = updatedDate
    self.weeksOnList = weeksOnList
    self.buyLinks = buyLinks
  }
}

错误原因

jsonData.results.listsb是[ListB]类型的数组,调用filter方法后,返回的仍然是符合条件的ListB实例组成的数组,而不是单个ListB对象。数组本身并没有books属性,只有单个ListB实例才有这个属性,因此报错。

解决方案

根据业务需求,有两种处理方式:

方式1:获取第一个符合条件的列表(推荐)

如果确定listNameEncoded == "hardcover-fiction"的列表只有一个,用first(where:)获取第一个元素,再访问其books属性,同时处理空值避免崩溃:

do{
    let jsonData = try JSONDecoder().decode(NYTTop100FictionModel.self, from: data!)
    guard let hardfictList = jsonData.results.listsb.first(where: { $0.listNameEncoded == "hardcover-fiction" }) else {
        print("未找到hardcover-fiction列表")
        return
    }
    books = hardfictList.books
} catch {
    print(String(describing: error))
}

方式2:合并所有符合条件列表的书籍

如果可能存在多个符合条件的列表,遍历所有结果合并书籍数组:

do{
    let jsonData = try JSONDecoder().decode(NYTTop100FictionModel.self, from: data!)
    let hardfictLists = jsonData.results.listsb.filter({ $0.listNameEncoded == "hardcover-fiction" })
    books = hardfictLists.flatMap { $0.books }
} catch {
    print(String(describing: error))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:05:57