0

So for testing purposes and following an online tutorial, I made an extremely simple app that Presents an action sheet with the ability to add one fruit.

Current model code:

    enum Section {
    case main
}

struct Fruit: Hashable {
    let uuid = UUID()
    var title: String
    
    static func == (lhs: Fruit, rhs: Fruit) -> Bool {
        return lhs.uuid == rhs.uuid
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(uuid)
    }
}

DataSource

dataSource = UITableViewDiffableDataSource(tableView: tableView, cellProvider: { tableView, indexPath, itemIdentifier in
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = itemIdentifier.title
        return cell
    })

Code that updates DataSource

    @objc func didTapAdd() {
    let actionSheet = UIAlertController(title: "Select Fruit", message: nil, preferredStyle: .actionSheet)
    actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    actionSheet.addAction(UIAlertAction(title: "Fruit \(1)", style: .default, handler: { [weak self] _ in
        let fruit = Fruit(title: "Fruit: \(1)")
        self?.fruits.append(fruit)
        self?.updateDataSource()
    })) present(actionSheet, animated: true)


@objc func add2() {
    let fruit = Fruit(title: "Fruit: \(1)")
    if !fruits.contains(fruit) {
        self.fruits.append(fruit)
        self.updateDataSource()
    }
    
}

func updateDataSource() {
    var snapshot = NSDiffableDataSourceSnapshot<Section, Fruit>()
    snapshot.appendSections([.main])
    snapshot.appendItems(fruits)
    dataSource.apply(snapshot, animatingDifferences: true)
}

So whats happening is once I call add2 the Fruit 1 is duplicated on the tableView, I need to ignore it if its the same object. How can I accomplish this? this is a quick representation of what I am trying to do on my main app, I basically need to populate CollectionViewCells from data from an Endpoint and from in app logic. Thing is the API gets called on every viewDidLoad, so I need to somehow ignore duplicates. Thanks!

stompy
  • 227
  • 1
  • 13
  • You're comparing based on title or based on UUID? If it's based on title, your equal operator (==) should be comparing lhs.title == rhs.title so that your .contains() function looks at title and not UUID. – paprika Jun 18 '22 at 14:28
  • Initially I was comparing with UUID as the example on this post, but that would cause cells to be duplicated every time I called updateDataSource with my Fruits array, so Im using title now which seems to be working fine. Something feels wrong using a title as a way to identify an object and conform to Hashable though. I am probably missing something. – stompy Jun 22 '22 at 20:01

0 Answers0