How to make Base class property generic in swift so can use with multiple model type?

226 Views Asked by At

I want the property "cellViewModel" as generic so I can reuse BaseCustomCell with a different types of models. Ex.

 struct CELLVIEWMODEL {
   var name: String
   var address: String
 }
 class BaseCustomCell: UITableViewCell {
       var cellViewModel: CELLVIEWMODEL  //should support different model types CELLVIEWMODEL1,CELLVIEWMODEL2
       {
        didSet() {
          setValuesInSubClasses
        }
      }
      func setValuesInSubClasses() {
       //subclass will implement
      }
 }

 class subCell: BaseCustomCell {
     override func setValuesInSubClasses() {
       //set value from cellViewModel
      }
 }

//This is how i am setting from cellForRowAtIndexPath method:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: viewModel.getCellId(), for: indexPath) as! BaseCustomCell
        cell.cellViewModel = viewModel.getCellModelAtIndexPath(indexPath) //this will set values for subclasses
        return cell
    }

Now, I am creating new BaseCustomCell each time for different types of cellViewModel. Could you help with any solution?

1

There are 1 best solutions below

4
On BEST ANSWER

There are several ways to achieve your goals.

You can make the actual BaseCustomCell glass generic, but be aware if you use Storyboards, this isn't a solution, since you'd need to hardcode the generic type into the storyboard.

The other solution that works with storyboards too is to declare your viewmodel as a protocol, then you can replace it with any concrete implementation of the protocol.

protocol CellViewModel {
    var name: String { get }
    var address: String { get }
}

class BaseCustomCell: UITableViewCell {
    var cellViewModel: CellViewModel {
        didSet() {
            setValuesInSubClasses
        }
    }
    
    func setValuesInSubClasses() {
       //subclass will implement
    }
}

class SubCell: BaseCustomCell {
     override func setValuesInSubClasses() {
       //set value from cellViewModel
      }
 }

And then your viewModel.getCellModelAtIndexPath should have a return type of CellViewModel, so it can return any type that conforms to the protocol.

So you simply need to declare your concrete cell view models like class FirstCellViewModel: CellViewModel { ... }, etc. and you can return them from getCellModelAtIndexPath