Search code examples
iosswiftuitableviewuikitrx-swift

RXSwift kept warning me tableView.rx.items(dataSource) not conforming to RxTableViewDataSourceType when binding data


I am trying to implement a tableView by using RxTableViewSectionedAnimatedDataSource, I set all the subclasses correct, when I try to bind dataSource to my tableView, the compiler keeps warning me

Instance method 'items(dataSource:)' requires that 'TableViewSectionedDataSource' conform to 'RxTableViewDataSourceType'

enter image description here

Here is the code

        let tableView = UITableView()
        let dataSource = RxTableViewSectionedAnimatedDataSource<CustomSectionDataType>(configureCell: { dataSource, tableView, indexPath, item in
            
            return UITableViewCell()
        })
        
        dataSource.titleForHeaderInSection = { (ds, section) in
            let sectionModel = ds.sectionModels[section]
            return sectionModel.header
        }
    
        let sectionDatas = [CustomSectionDataType(ID: "1", header: "test", items: ["WTF!"])]
 
        let items = BehaviorRelay(value: [sectionDatas])
        
    
        items
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: self.disposeBag)

Custom Section Class

struct CustomSectionDataType {
    var ID: String
    var header: String
    var items: [Item]
    
}


extension CustomSectionDataType: AnimatableSectionModelType {

    typealias Item = String
    typealias Identity = String
   
    var identity: String {
      return ID
    }
    
    init(original: CustomSectionDataType, items: [Item]) {
      self = original
      self.items = items
    }
    
}

Solution

  • You have a too deeply nested array for your items type.

    The type is defined as BehaviorRelay<[[CustomSectionDataType]]> when it should be BehaviorRelay<[CustomSectionDataType]>.

    Also, consider using a typealias instead of creating your own custom type:

    typealias CustomSectionDataType = AnimatableSectionModel<String, String>
    

    or if you have two headers that are the same but with different IDs then:

    struct CustomModel: IdentifiableType {
        var identity: String
        var header: String
    }
    
    typealias CustomSectionDataType = AnimatableSectionModel<CustomModel, String>
    

    It makes life a bit easier.