In my project I am using a UITableView with a UITableViewDiffableDataSource. I love how easy it is to get up and running with very little boiler plate code and all the free animations. It's a great API!
In my project I have implemented a trailing swipe action AND a context menu action. The action allows the user to mark the message read or unread similar to the native Mail app in iOS.
I had assumed that this could be accomplished using the following code:
enum Section: CaseIterable {
case main
}
struct Item: Hashable {
var isRead: Bool
let identifier = UUID()
		/* Hashable */
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.identifier == rhs.identifier
}
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
class ViewController: UITableViewController {
		var dataSource: UITableViewDiffableDataSource<Section, Item>!
		...
		func markItemRead(_ item: Item) {
				var snapshot = dataSource.snapshot()
				var updatedItem = item
updatedItem.isRead = true
snapshot.reloadItems(updatedItem)
self.dataSource.apply(snapshot)
		}
}
I assumed the method reloadItems(_:) was intended to replace using reloadRows(at:with:) since that method is not available to you when you are using UITableViewDiffableDataSource.
So far I have run into this error - https://developer.apple.com/forums/thread/651333, usually when I am using a struct for my model object with inferred Hashable conformance OR even sometimes with a class, but I can't see to put my finger on it.
Once I am past getting that error, I am noticing that the method doesn't seem to do what I want. The dataSource holds onto the old object with the old value for isRead. So when the cell is reloading it's view, it doesn't change at all, because it receives the old value for the isRead property. That lead me to this workaround:
func markItemRead(_ item: Item) {
let oldSnapshot = dataSource.snapshot()
let oldItems = oldSnapshot.itemIdentifiers(inSection: .main)
let updatedItems: [Item] = oldItems.map {
if $0 == item {
var updatedItem = $0
updatedItem.isRead = true
return updatedItem
}
return $0
}
var snapshot = NSDiffableDataSourceSnapshot<Section, ConversationsController.Conversation>()
snapshot.appendSections([.main])
snapshot.appendItems(updatedItems, toSection: .main)
dataSource.apply(snapshot)
DispatchQueue.main.async {
var snapshot = self.dataSource.snapshot()
snapshot.reloadItems([item])
self.dataSource.apply(snapshot)
self.refreshBadge()
}
}
The DispatchQueue.main.async was a last ditch effort to get it working and it finally did, but this definitely does not feel right.
If someone has been able to figure it out. I would appreciate some help in understanding what/how reloadItems(_:) is intended to work.
I have a feeling it all comes down to Hashable but I am not sure exactly what. Thanks!
Post
Replies
Boosts
Views
Activity
I am repeatedly seeing this error when attempting to call reloadItems(_:) on a NSDiffableDataSourceSnapshot instance.** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: indexPath || ignoreInvalidItems'
var dataSource: UITableViewDiffableDataSource<Section, Foo>!
func incrementFoo(_ foo: Foo) {
var snapshot = dataSource.snapshot()
var foo = foo
foo.upvoteCount += 1
snapshot.reloadItems([foo])
dataSource.apply(snapshot)
}
I am working on an app that supports incoming VoIP calls and this requires using the PushKit APIs. I was wondering if anyone is aware of a 3rd party service push notification service that is reliable, easy to implement and supports the PushKit APIs, including VoIP pushes?