JSON 在 Table 视图中使用时出现编码错误

JSON codable error while using in Table View

我正在使用 newsapi.org api 构建一个新闻应用程序。我能够从服务器获取数据并使用 JSON 解码器对其进行解码,但问题在于当我通过提供将文章数组作为数据源分配给 table 视图时,我得到了一个文章数组部分中的行数作为文章数组计数我收到一条错误消息,指出在 numberofrowsinsetction 方法中隐式展开可选值时意外发现 nil。

我能够在调试控制台中打印 articles.count,目的是在将 count.But 分配给 numberrowsinsection 方法时出现此错误。

网络服务代码

import Foundation


class NetworkService{
    
    
    static  let  sharedobj = NetworkService()
    let session = URLSession.shared
    
    
   private let HEADLINES_URL = "https://newsapi.org/v2/top-headlines?country=in&apiKey=API_key_HERE"
    
    public func getHeadLines(onSuccess: @escaping ([Articles]) -> Void)
    {
        let datatask = session.dataTask(with: URL(string: HEADLINES_URL)!, completionHandler: { (data, response, error) in
            
            DispatchQueue.main.async {
                
                do
                {
                    let decoder = try JSONDecoder().decode(Welcome.self, from: data!)
                    onSuccess(decoder.articles!)
                }
                
                catch
                {
                    print(error.localizedDescription)
                }
                
               
            }
            
            
            
            
            
        
        })
        
        datatask.resume()
        
        
        
    }

查看控制器代码

import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{
   
   
    var articles: [Articles]!
    var newsurl: String!
    
    @IBOutlet weak var headlinestableview: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
       
        self.headlinestableview.delegate = self
        self.headlinestableview.dataSource = self
        
        NetworkService.sharedobj.getHeadLines { (a) in
            self.articles = a
            
            print(self.articles.count)
            
           
            
        }
       
       
     
        
            
        
     
        
       
        
        
        
        
       
        
        
    }

    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return articles.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        
       if let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? HeadLinesCellTableViewCell
        {
            
            let data = articles[indexPath.row]
            
            cell.updateCell(title:data.title ?? "Not Found", body: data.content ?? "No Body", imgurl: data.urlToImage ?? "https://en.wikipedia.org/wiki/Pages_(word_processor)#/media/File:Pages_Icon.png")
            
            newsurl = data.url
           
            return cell
            
        }
        
        
        return UITableViewCell()
        
    }
    
    
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        performSegue(withIdentifier: "segue", sender: self)
        
    }
    
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if let destinationVC = segue.destination as? BrowserVC
        {
            destinationVC.url = newsurl
        }
        
    }

}

模型结构(使用 JSON 到 Swift 网站生成)

struct Welcome : Codable {
    let status : String?
    let totalResults : Int?
    let articles : [Articles]?

    enum CodingKeys: String, CodingKey {

        case status = "status"
        case totalResults = "totalResults"
        case articles = "articles"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        status = try values.decodeIfPresent(String.self, forKey: .status)
        totalResults = try values.decodeIfPresent(Int.self, forKey: .totalResults)
        articles = try values.decodeIfPresent([Articles].self, forKey: .articles)
    }

}



struct Articles : Codable {
    let source : Source?
    let author : String?
    let title : String?
    let description : String?
    let url : String?
    let urlToImage : String?
    let publishedAt : String?
    let content : String?

    enum CodingKeys: String, CodingKey {

        case source = "source"
        case author = "author"
        case title = "title"
        case description = "description"
        case url = "url"
        case urlToImage = "urlToImage"
        case publishedAt = "publishedAt"
        case content = "content"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        source = try values.decodeIfPresent(Source.self, forKey: .source)
        author = try values.decodeIfPresent(String.self, forKey: .author)
        title = try values.decodeIfPresent(String.self, forKey: .title)
        description = try values.decodeIfPresent(String.self, forKey: .description)
        url = try values.decodeIfPresent(String.self, forKey: .url)
        urlToImage = try values.decodeIfPresent(String.self, forKey: .urlToImage)
        publishedAt = try values.decodeIfPresent(String.self, forKey: .publishedAt)
        content = try values.decodeIfPresent(String.self, forKey: .content)
    }

}


// MARK: - Source
struct Source : Codable {
    let id : String?
    let name : String?

    enum CodingKeys: String, CodingKey {

        case id = "id"
        case name = "name"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decodeIfPresent(String.self, forKey: .id)
        name = try values.decodeIfPresent(String.self, forKey: .name)
    }

}

TableView单元格代码

import UIKit

class HeadLinesCellTableViewCell: UITableViewCell {

    
    @IBOutlet weak var headlinesimageview: UIImageView!
    

    @IBOutlet weak var headlinestitlelbl: UILabel!
    
    @IBOutlet weak var headlinesbodylbl: UILabel!
    
    
    
    func updateCell(title: String,body: String,imgurl: String)
    {
        headlinestitlelbl.text = title
        headlinesbodylbl.text = body
        
        DispatchQueue.global(qos: .userInitiated).async {
            
            if let data = try? Data(contentsOf: URL(string: imgurl)!)
        {
                if let image = UIImage(data: data)
                {
                    DispatchQueue.main.async {
                        self.headlinesimageview.image = image
                    }
                }

            
        }
        
        
    }
    
  
    
    
}
}


    
          
                
                
      

      
            
            
            
            
                
                
      }
            
        
            
            
            
            
            
            
            
            

        
        
        
    
    
    

而不是这个:

var articles: [Articles]!

使用它来声明文章:

var articles = [Articles]()

更新:

在您的 didSelectRow 方法中执行此操作:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
   
    let article = articles[indexPath.row]
    performSegue(withIdentifier: "segue", sender: article)
    
}