告诉 numberOfRowsInSection 在使用 MVVM 架构在闭包中使用 JSONDecoder 解析 JSON 后它需要多少行

Posted

技术标签:

【中文标题】告诉 numberOfRowsInSection 在使用 MVVM 架构在闭包中使用 JSONDecoder 解析 JSON 后它需要多少行【英文标题】:Telling numberOfRowsInSection how many rows it needs after parsing JSON with JSONDecoder in closure using MVVM architecture 【发布时间】:2019-05-29 02:11:48 【问题描述】:

我正在使用 MMVM 架构。

基本上我有这个函数来解析viewModelProtocol扩展中的JSON作为默认实现,我的viewModels符合这个协议。大多数视图模型填充标准视图没有任何问题,除了填充 tableVIew 但我无法告诉 numberOfRowsInSection 它需要多少行。

func setWithJSON<T>(completion: @escaping (T) -> Void, error: @escaping (Error) -> Void, service: Services) where T : Decodable 
    let failure: (Error) -> Void =  error in
        self.dataFetchError?(error)
    

    let completion: (Data) -> Void =  data in

        do 
            let parsedJSON = try JSONDecoder().decode(T.self, from: data)
            completion(parsedJSON)
         catch 
            self.dataFetchError?(error)
        
        return
    

    QueryAPI.shared.setServiceURL(service)
    QueryAPI.shared.fetchData(failure: failure, completion: completion)

有了它,我得到了一个通用类型的 parsedJSON

我正在使用视图中的函数来填充 cellForRowAt indexPath: 中的单元格,如下所示。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier") as! ExperienceViewCell

    let error: (Error) -> Void =  error in
        self.handleError(error)
    

    let completion: ([Experience]) -> Void =  experiences in
        DispatchQueue.main.async  [ weak cell ] in
            cell?.companyLabel.text = experiences[indexPath.row].company
            cell?.positionLabel.text = experiences[indexPath.row].position
            cell?.websiteLabel.text = experiences[indexPath.row].website
            cell?.startDateLabel.text = experiences[indexPath.row].startDate
            cell?.endDateLabel.text = experiences[indexPath.row].endDate
            cell?.summaryTextView.text = experiences[indexPath.row].summary
            cell?.highLightsTextView.text = experiences[indexPath.row].highlights
        
    

    viewModel.setWithJSON(completion: completion, error: error, service: .workExperience)
    self.viewModel.dataFetchError =  error in
        self.handleError(error)
    

    return cell

通过这种方式,我在闭包中获得了一个结构体 Experience 数组,并使用它的每个元素来填充我的 tableView 的行。

但我没有办法告诉方法 numberOfRowsInSection 我们需要多少行,所以我正在对其进行硬编码,但这不是我需要的。

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 7

有什么方法可以在视图加载时获得一组经验,以便我可以告诉方法它应该返回多少行。

提前致谢。

【问题讨论】:

【参考方案1】:

我看到的问题是您在 tableView:cellForRowAt: 函数中调用服务,这不是一个好方法。

尝试在你的 viewController 中设置一个变量var experiences: [Experience] = []

viewDidLoad函数中调用你的服务

func viewDidLoad() 
    super.viewDidLoad()
    let completion: ([Experience]) -> Void =  experiences in
        DispatchQueue.main.async  [ weak self ] in
            self?.experiences = experiences
            self?.tableView.reloadData()
        
    
    viewModel.setWithJSON(completion: completion, error: error, service: .workExperience)
    self.viewModel.dataFetchError =  error in
        self.handleError(error)
    

在函数tableView:numberOfRowsInSection:中可以返回experiences.count

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return experiences.count

最后,在函数tableView:cellForRowAt: 中,您可以输入代码来更新单元格:

cell.companyLabel.text = experiences[indexPath.row].company
cell.positionLabel.text = experiences[indexPath.row].position
cell.websiteLabel.text = experiences[indexPath.row].website
cell.startDateLabel.text = experiences[indexPath.row].startDate        
cell.endDateLabel.text = experiences[indexPath.row].endDate
cell.summaryTextView.text = experiences[indexPath.row].summary
cell.highLightsTextView.text = experiences[indexPath.row].highlights

使用tableView.reloadData(),您将在收到体验列表后再次调用函数tableView:numberOfRowsInSection:

【讨论】:

是的,做到了!,我无法使用我在协议中为该视图提供的默认通用 setWithJSON 实现,但是在使用为该视图构建的特定实现之后,它就像一个魅力。谢谢

以上是关于告诉 numberOfRowsInSection 在使用 MVVM 架构在闭包中使用 JSONDecoder 解析 JSON 后它需要多少行的主要内容,如果未能解决你的问题,请参考以下文章

对成员 '(_:numberOfRowsInSection:)' 的模糊引用

如何返回 numberOfRowsInSection?

数组未与 tableView(numberOfRowsInSection) 方法连接

numberOfRowsInSection:核心数据和多个部分的方法

numberOfRowsInSection:未在 reloadData 上调用

numberOfRowsInSection 多次调用但 cellForRowAtIndexPath 从未调用