ios - 从 'didset' JSON 解码数组数据返回 Nil 值

标签 ios json swift

我似乎无法设置下面的电视节目和缩略图。我正在正确生成数据数组,因为 print(shows) 语句正确打印了所有项目。任何人都可以看到我要去哪里错了。没有错误,但我的观点是空的,没有图像或标题。 这是 TvController 类

class TvController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

var tvShows: [RecentTvList]? = []


func fetchTvItems()   {

    let jsonUrlString = "https://www.what-song.com/api/recent-tv?page=1"
    guard let url = URL(string: jsonUrlString) else
    {return}

    URLSession.shared.dataTask(with: url) { (data, response, err) in

        guard let data = data else {return}

        do {

            let shows =  try
                JSONDecoder().decode(RecentTvListData.self, from: data)
            print(shows)

            self.tvShows = shows.data

        } catch let jsonErr {
            print("Error serializing JSON", jsonErr)
        }

    }.resume()

override func viewDidLoad() {
    super.viewDidLoad()

    fetchTvItems()

    navigationItem.title = "TV"
    navigationController?.navigationBar.isTranslucent = false

    collectionView?.backgroundColor = .white

    collectionView?.register(TvCell.self, forCellWithReuseIdentifier: cellId)
    collectionView?.register(Header.self, forSupplementaryViewOfKind:
        UICollectionElementKindSectionHeader, withReuseIdentifier: headerId)
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if let count = tvShows?.count    {
        return count
    }

    return 0

}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! TvCell

    cell.televisionShow = tvShows?[indexPath.item]

    return cell
}
}

这是模型文件:

struct RecentTvListData: Decodable  {
var data: [RecentTvList]
}

struct RecentTvList: Decodable  {
var title: String?
var poster_url: String?
}

这是单元格的 View :所有 View / subview /约束都已正确设置,我只是懒得包含代码,因为它使所有这些变得过于臃肿。我非常确定问题出在模型或 Controller 上。

var tvShowsController: TvController?


var televisionShow: RecentTvList? {
    didSet {
        titleLabel.text = televisionShow?.title
        setupThumbnailImage()
        thumbnailImageView.image = UIImage(named: (televisionShow?.poster_url)!)
    }
}

let thumbnailImageView: UIImageView = {
    let imageView = UIImageView(image: #imageLiteral(resourceName: "stranger things poster"))
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.layer.cornerRadius = 6
    imageView.contentMode = .scaleAspectFill
    imageView.layer.masksToBounds = true
    return imageView
}()

let titleLabel: UILabel = {
    let title = UILabel()
    title.text = "Stranger Things"
    title.font = UIFont(name: "Montserrat", size: 17)
    title.translatesAutoresizingMaskIntoConstraints = false
    return title
}()

最佳答案

下载数据(即 URLSession.shared.dataTask(with: url) 之后的 block 中的所有代码)是一个异步操作,这意味着 iOS 在不同的线程上运行该代码它有足够的时间完成并立即继续执行当前(在本例中为主线程)线程。当您的 Collection View 加载并尝试显示其数据时,它尚未完成下载,因此没有数据可显示。您可以通过调用 reloadData 强制您的 Collection View 在数据下载完成后加载数据,如下所示:

URLSession.shared.dataTask(with: url) { (data, response, err) in

    guard let data = data else {return}

    do {

        let shows =  try
            JSONDecoder().decode(RecentTvListData.self, from: data)
        print(shows)

        self.tvShows = shows.data
        self.collectionView?.reloadData()

    } catch let jsonErr {
        print("Error serializing JSON", jsonErr)
    }

}.resume()

关于ios - 从 'didset' JSON 解码数组数据返回 Nil 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47465899/

相关文章:

ios - 使用 NSCoding 归档 UIImageView

ios 忽略 viewWillDisappear

ios - 如何从另一个变量<[团队]>观察变量<[游戏]>?

ios - 更改拉动刷新事件指示器

swift - SpriteKit 跨设备在 View 框架内生成对象

ios - Google App Indexing - 如何测试它?

iphone - 指定 "Left Detail" TableView 单元格的文本

json - 将 JSON 对象转换为 Buffer 并将 Buffer 转换为 JSON 对象

javascript - 如何检查一个 JavaScript 对象中的值是否存在于另一个对象中?

json - 如何在PowerShell中将HashTable正确转换为JSON?