George
George

Reputation: 49

Error when setting table datasource to a certain class

I'm currently learning how to make multiple cell types for a single tableView and I get an error when I try to set a datasource for the UITableView in Swift 4.

I get an error like this below

Cannot assign value of type 'ProfileViewModel.Type' to type 'UITableViewDataSource?'

The code I get this error message is this one

tableView?.dataSource = ProfileViewModel

Details about the code is below. This class is out of original ViewController class but I declared the class with UITableViewDataSource.

class ProfileViewModel: NSObject, UITableViewDataSource {
    var items = [ProfileViewModelItem]()

    init(profile: Profile) {
        super.init()
        guard let data = dataFromFile(filename: "ServerData") else {
            return
        }

        let profile = Profile(data: data)

        if let name = profile.fullName, let pictureUrl = profile.pictureUrl {
            let nameAndPictureItem = ProfileViewModelNameAndPictureItem(pictureUrl: pictureUrl, userName: name)
            items.append(nameAndPictureItem)
        }
        if let about = profile.about {
            let aboutItem = ProfileViewModelAboutItem(about: about)
            items.append(aboutItem)
        }
        if let email = profile.email {
            let dobItem = ProfileViewModelEmailItem(email: email)
            items.append(dobItem)
        }
        let attributes = profile.profileAttributes
        if !attributes.isEmpty {
            let attributesItem = ProfileViewModelAttributeItem(attributes: attributes)
            items.append(attributesItem)
        }
        let friends = profile.friends
        if !profile.friends.isEmpty {
            let friendsItem = ProfileViewModeFriendsItem(friends: friends)
            items.append(friendsItem)
        }
    }

}

extension ProfileViewModel {
    func numberOfSections(in tableView: UITableView) -> Int {
        return items.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items[section].rowCount
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // config
    }
}

Can anybody help me please?

Upvotes: 1

Views: 43

Answers (2)

Rob
Rob

Reputation: 437882

You are referring to the class, but you need to refer to an instance of that class. Thus, you need to instantiate your ProfileViewModel:

class ViewController {
    @IBOutlet weak var tableView: UITableView!

    var profileViewModel: ProfileViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let profile = ...
        profileViewModel = ProfileViewModel(profile: profile)   // it doesn't look like you need this parameter, so remove it if you don't really need it

        tableView?.dataSource = profileViewModel

        ...
    }
}

Note, I didn't just do the following directly:

tableView?.dataSource = ProfileViewModel(profile: ...)

The problem is that the tableView doesn't keep a strong reference to its dataSource, and this will be deallocated. You need to keep your own strong reference to it, and then use that reference.

Upvotes: 0

Sweeper
Sweeper

Reputation: 272760

This line:

tableView?.dataSource = ProfileViewModel

You are trying to assign a type to tableView.dataSource. A table view's datasource can't possibly be a type, right? It should be an object of a type that conforms to UITableViewDataSource.

I think you meant

tableView?.dataSource = self

Upvotes: 1

Related Questions