1

I have a Data Source with multiple sections and objects. When creating my Data Source I can only access the section or the item type. I need to access both, is there a cleaner way to do this? My model is below;

enum BrowseSectionType: Hashable {
    case featured
    case latest
    case popular
    case expiring
    case link
}

struct BrowseSection: Hashable {
    var section: BrowseSectionType
    var title: String?
    var subtitle: String?
    var items: [BrowseItem]
}

enum BrowseItem: Hashable {
    case discount(DiscountItem)
    case link(LinkItem)
}

enum LinkItemType: Hashable {
    case category
    case saved
}

struct LinkItem: Hashable {
    var item: LinkItemType
    var text: String
}

Data Source;

fileprivate func setUpDataSource() {
        dataSource = BrowseDataSource(collectionView: collectionView, cellProvider: { [weak self] (collectionView, indexPath, item) -> UICollectionViewCell? in
            
            guard let self = self else {
                return UICollectionViewCell()
            }
            
            let section = self.sections[indexPath.section].section
            switch section {
            case .featured:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LargeDiscountCell.identifier,
                                                              for: indexPath) as! LargeDiscountCell
                return cell
            case .latest, .expiring:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LargeDiscountCell.identifier,
                                                              for: indexPath) as! MediumDiscountCell
                return cell
            case .popular:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LargeDiscountCell.identifier,
                                                              for: indexPath) as! SmallDiscountCell
                return cell
            case .link:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LinkCell.identifier,
                                                                  for: indexPath) as! LinkCell
                return cell
            }
        })

I can do switching on the item to get the item object as per the below, however, then I need to switch sections.

    switch item {
    case .discount(let discountItem):
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LargeDiscountCell.identifier,
                                                      for: indexPath) as! LargeDiscountCell
        cell.bind(discountItem, indexPath: indexPath)
        return cell
    case .link(let linkItem):
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LinkCell.identifier,
                                                          for: indexPath) as! LinkCell
        cell.bind(linkItem)
        return cell
    }

There must be a better way to handle this...

David Henry
  • 1,972
  • 20
  • 43

0 Answers0