-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
IngmarStein Jun 11, 2019 12:41 PM (in response to anwill999)This doesn't look ready, yet. The example is clearly wrong, as the cast operates on unrelated types and always fails when you add the missing generic paramaters, given the following class declarations in beta 1:
open class NSDiffableDataSourceSnapshotReference<sectionidentifiertype, itemidentifiertype=""> : NSObject, NSCopying where SectionIdentifierType : AnyObject, ItemIdentifierType : AnyObject { public class NSDiffableDataSourceSnapshot<sectionidentifiertype, itemidentifiertype=""> where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable {
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
IngmarStein Jun 11, 2019 12:56 PM (in response to IngmarStein)Also, if you try to use the NSDiffableDataSourceSnapshotReference that is passed to your delegate in controller(_, didChangeContentWith:), you get all sorts of type errors which seem to indicate a problem with how this type is imported into Swift:
(lldb) po snapshot.sectionIdentifiers Precondition failed: NSArray element failed to match the Swift Array Element type Expected NSManagedObjectID but found __NSCFConstantString: … (lldb) po snapshot.itemIdentifiers Precondition failed: NSArray element failed to match the Swift Array Element type Expected NSString but found NSTemporaryObjectID_0: …
This lets me think that NSDiffableDataSourceSnapshotReference<NSManagedObjectID, NSString> should probably be NSDiffableDataSourceSnapshotReference<NSString, NSManagedObjectID>.
-
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
funkenstrahlen Jun 15, 2019 12:41 PM (in response to anwill999)Can confirm this issue when I try to use this on a UITableView. I hope Apple addresses this in a future beta. Everyone send a bugreport!
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
IngmarStein Jun 17, 2019 2:05 PM (in response to funkenstrahlen)Not yet fixed in beta 2.
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
anwill999 Jul 4, 2019 12:31 PM (in response to IngmarStein)Tried in Beta 3 but no luck. Has anyone else tried in Beta 3?
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
kovapps Jul 13, 2019 10:09 AM (in response to anwill999)I was able to get the NSDiffableDataSourceSnapshotReference working in beta 3. Here is my controller::didChangeContentWith method:
func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference<nsstring, nsmanagedobjectid="">) { let resolvedSnapshot = NSDiffableDataSourceSnapshot<string, model="">() for section in snapshot.sectionIdentifiers { resolvedSnapshot.appendSections([section as String]) resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map { controller.managedObjectContext.object(with: $0) as! Model }, toSection: section as String) } dataSource.apply(resolvedSnapshot, animatingDifferences: true) }
dataSource is defined as:
dataSource = UICollectionViewDiffableDataSource<String,Model>(collectionView: collectionView) { ... }
I'm curious as to whether this mapping from one snapshot to the snapshot that the dataSource expects is going to be the typical approach.
-
-
-
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
funkenstrahlen Jun 21, 2019 4:04 AM (in response to anwill999)Maybe this question is related: What is the difference between NSDiffableDataSourceSnapshot and NSDiffableDataSourceSnapshotReference?
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
Shaps Jun 22, 2019 6:57 AM (in response to funkenstrahlen)From what I can see its the Reference version just enforces reference types, i.e. classes.
-
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
Shaps Jun 22, 2019 7:02 AM (in response to anwill999)It looks as if this isn't supported directly yet. However I did manage to get it to work by pulling out the associated data. This assumes a single section so you'll need to adjust for your own implenentation however it does work and appears to update, animate etc as expected. Given the Apple sample code I was also able to add the publisher approach for cell field updates and also remove the dataSource methods
for numberOfItems, etc...
<nsmanagedobjectid, nsstring=""><section, tag="">
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference<NSManagedObjectID, NSString>) { // NOTE: Section.main is an enum that represents my single section let diffable = NSDiffableDataSourceSnapshot<Section, Tag>() diffable.appendSections([.main]) diffable.appendItems(dataProvider.fetchedResultsController.fetchedObjects ?? [], toSection: .main) dataSource.apply(diffable, animatingDifferences: true) }
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
mbarriault Jun 23, 2019 12:33 PM (in response to anwill999)I'm also running into this issue, but a bit of type finagling I have it mostly working. My remaining issue is that I can't figure out how to properly populate the collection view on load.
My type order is, as IngmarStein suggests, string before object ID,
typealias Snapshot = NSDiffableDataSourceSnapshotReference<NSString, NSManagedObjectID> typealias DataSource = UICollectionViewDiffableDataSourceReference<NSString, NSManagedObjectID>
extension ViewController: NSFetchedResultsControllerDelegate { func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference<NSManagedObjectID, NSString>) { let newSnapshot = Snapshot() newSnapshot.appendSections(withIdentifiers: snapshot.sectionIdentifiers as [AnyObject] as! [NSString]) newSnapshot.appendItems(withIdentifiers: snapshot.itemIdentifiers as [AnyObject] as! [NSManagedObjectID]) self.dataSource.applySnapshot(newSnapshot, animatingDifferences: true) } }
The secionIdentifiers are constant each launch, but I can't see how to get them out of NSFetchedResultsController without calling didChangeContent. Notably, section.name is nil. I can populated on view load by inventing temporary section titles
let snapshot = Snapshot() if let sections = self.fetched.sections { let sectionMap = [NSString: NSFetchedResultsSectionInfo](uniqueKeysWithValues: sections.map {section -> (NSString, NSFetchedResultsSectionInfo) in return (UUID().description as NSString, section)}) snapshot.appendSections(withIdentifiers: sectionMap.compactMap {$0.key}) for section in sectionMap { snapshot.appendItems(withIdentifiers: (section.value.objects as! [NSManagedObject]).map {$0.objectID}, intoSectionWithIdentifier: section.key) } } self.dataSource.applySnapshot(snapshot, animatingDifferences: false)
These IDs will be replaced on first change. I don't know what effect this might have on a more complicated fetch, but so far it seems to not animate a large rearrangement of existing objects into a new section.
I have also submitted a feedback request, FB6162037.
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
alemar11 Aug 1, 2019 12:25 AM (in response to mbarriault)Did you receive any updates from your feedback request?
-
-
Re: Unable to cast NSDiffableDataSourceSnapshotReference
mattn Oct 21, 2019 9:11 AM (in response to anwill999)It's a straightforward cast:
func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { let snapshot = snapshot as NSDiffableDataSourceSnapshot<string,nsmanagedobjectid> self.ds.apply(snapshot, animatingDifferences: false) }
I'm assuming here that your diffable data source is typed with generic resolutions String, NSManagedObjectID. In your cell population function you go back to the fetched results controller, fetch out the actual object by index path, and populate the cell from its properties.