My goal is to display data coming from a web service called News API into a collection view controller. Below is the data model and network manager.
struct News: Codable { var status: String? var totalResults: Int? var articles: [Article]? var article: Article? enum CodingKeys: String, CodingKey { case status = "status" case totalResults = "totalResults" case articles = "articles" } } // MARK: - Article struct Article: Codable { var source: Source? var author: String? var title: String? var articleDescription: String? var url: String? var urlToImage: String? var publishedAt: String? var content: String? enum CodingKeys: String, CodingKey { case source = "source" case author = "author" case title = "title" case articleDescription = "description" case url = "url" case urlToImage = "urlToImage" case publishedAt = "publishedAt" case content = "content" } } // MARK: - Source struct Source: Codable { var id: ID? var name: Name? enum CodingKeys: String, CodingKey { case id = "id" case name = "name" } } enum ID: String, Codable { case engadget = "engadget" case techcrunch = "techcrunch" case theVerge = "the-verge" } enum Name: String, Codable { case engadget = "Engadget" case lifehackerCOM = "Lifehacker.com" case techCrunch = "TechCrunch" case theVerge = "The Verge" } class NetworkManger{ static let shared = NetworkManger() private let baseURL: String private var apiKeyPathCompononent :String private init(){ self.baseURL = "https://newsapi.org/v2/everything?q=NFT&sortBy=popularity&" self.apiKeyPathCompononent = "apiKey=d32071cd286c4f6b9c689527fc195b03" } private var jsonDecoder:JSONDecoder = { let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase return decoder }() func getArticles() { AF.request(self.baseURL + self.apiKeyPathCompononent, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).response { (responseData) in guard let data = responseData.data else {return} do { let news = try self.jsonDecoder.decode(News.self, from: data) let nc = NotificationCenter.default nc.post(name: Notification.Name("didFinishParsing"), object: nil) } catch { print(error) } } } } It can display data from the web service to the console. The problem is that it can not show data to the collection view in NewsVC. I've done all necessary steps such as implementing the collection view data source, using an observer to alert the NewsVC that the JSON is parsed, setting the collection view layout, and registering the cell, but nothing seems to work. The code below is the NewVc and News grid; News Vc is meant to show the contents of the. class NewsVC: UIViewController { var news = Article
@IBOutlet weak var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() configureCollection() NetworkManger.shared.getArticles() } func configureCollection(){ collectionView.delegate = self collectionView.dataSource = self let collectionviewFlowLayout = UICollectionViewFlowLayout() collectionviewFlowLayout.scrollDirection = .vertical collectionviewFlowLayout.itemSize = CGSize(width: 188.0, height: 264.0) collectionviewFlowLayout.minimumInteritemSpacing = 10.0 collectionView.collectionViewLayout = collectionviewFlowLayout NotificationCenter.default.addObserver(self, selector: #selector(refreshcollectionView), name: Notification.Name("didFinishParsing"), object: nil) } @objc func refreshcollectionView(_ notification:Notification) { guard let news = notification.object as? Article else { return} print("News == \(news)") self.news = [news] print("Coount == \(self.news.count)") DispatchQueue.main.async { self.collectionView.reloadData() } } extension NewsVC:UICollectionViewDataSource , UICollectionViewDelegate{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { news.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! NewsGridCell let stories = news[indexPath.item] cell.setCells(stories) cell.backgroundColor = UIColor.red return cell } class NewsGridCell: UICollectionViewCell {
@IBOutlet weak var newsImage: UIImageView! @IBOutlet weak var newsDescription: UILabel! @IBOutlet weak var author: UILabel! func setCells(_ news:Article){ upDateUI(newDescription:news.articleDescription, author: news.author) } private func upDateUI(newDescription:String? , author:String?){ self.newsDescription.text = newDescription self.author.text = author } }
https://stackoverflow.com/questions/66926886/collection-view-not-showing-data April 03, 2021 at 09:08AM
没有评论:
发表评论