Post

Replies

Boosts

Views

Activity

Problem with associatedtype in a protocol - "Member '<method>' cannot be used on value of type 'any <protocol>';
I am having a problem trying to resolve a problem with an associated type in a protocol. Here is the code stripped down to minimum for demonstration protocol Protocol1 { associatedtype DataItem func protocolMethod(item : DataItem) } protocol Protocol2 { associatedtype AType1: Hashable //... } class Class1<Type1: Protocol2>: NSObject { typealias Item = Type1.AType1 var delegate : (any Protocol1)? private func method1(item: Item) { delegate?.protocolMethod(item : item) //ERROR HERE } } The error occurring at "ERROR HERE" is: Member 'protocolMethod' cannot be used on value of type 'any Protocol1'; consider using a generic constraint instead This all works if the item parameter is not defined on protocolMethod (and its invocation where the error occurs). And I think I get why it's happening, that it can't determine the type of item in the invocation. Is there a way to accomplish this? I have played with it quite a bit with generic params, etc. but still can't find the right formula to make it work. Am I just asking too much from Swift in this case?
1
0
1.4k
Jan ’23
NSFetchedResultsControllerDelegate didChangeContentWith called with temporary CoreData Ids on save
Currently pretty confused about a DiffableDatasource, FetchedResultsController, &amp; CollectionView behavior. As a result of calling the method below, the NSFetchedResultsController delegate didChangeContentWith method is called with a snapshot that contains temporary NSManagedObjectIds. As a result, when cell registration vend block is called, it is given the temporary id as the item id which no longer is valid as the object has been saved. So trying to retrieve the object to create the configuration for the cell fails. Here is snippet of the log produced by the code below (adding 2 new items): pre-save didChangeContentWith Printing description of snapshot: NSDiffableDataSourceSnapshot 0x2838cb660: numberOfSections:1 numberOfItems:5; generation=4EAC45D6-A145-4F4C-8220-F6EE212C3F88; sectionCounts=[_UIDataSourceSnapshotter - 0x283ab3fe0:(0:5)] [d69e6c783a242772974cfc99189691b88e9d37c3: {0x94cd5e7b72fa7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p2 0x94cd5e7b729a7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p1 0x94cd5e7b72da7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p3 0x283a5a8e0 x-coredata:///PlaylistItem/t710323F2-7D5C-40C4-A055-F75F8E0D0C852 0x283aaf8a0 x-coredata:///PlaylistItem/t710323F2-7D5C-40C4-A055-F75F8E0D0C853}] post save getting cell for [0, 0] with objid: 0x94cd5e7b72fa7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p2 getting cell for [0, 1] with objid: 0x94cd5e7b729a7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p1 getting cell for [0, 2] with objid: 0x94cd5e7b72da7e83 x-coredata://988F6C04-1529-454C-BBCB-2DE610F7AFC0/PlaylistItem/p3 getting cell for [0, 3] with objid: 0x283a5a8e0 x-coredata:///PlaylistItem/t710323F2-7D5C-40C4-A055-F75F8E0D0C852 Fatal error: Managed object should be available: file Stoppage/PlaylistDetail2FRCViewModel.swift, line 118 2021-05-05 11:43:10.611464-0500 Stoppage[5055:2243531] Fatal error: Managed object should be available: file Stoppage/PlaylistDetail2FRCViewModel.swift, line 118 The datasource is passing the temporary id (which is no longer available post save) to the cell creation. I can fully accept that I might be being dim and not seeing my mistake, but I just can't see it. It seems to me that the snapshot generated from the save should have the real objectIds rather than the temps. The end result is that the fatalError() in the cell registration is called as it can't find the object with the temp id. Insert items method     func addItemsToPlaylist(_ newItemCollection:MPMediaItemCollection)     {         guard let playlist = self.playlist else {fatalError()}       AppDelegate.appDelegate().persistentContainer.viewContext.performAndWait {             let pl = AppDelegate.appDelegate().persistentContainer.viewContext.object(with: playlist.objectID) as! Playlist             pl.addMediaItems(newItemCollection)             if AppDelegate.appDelegate().persistentContainer.viewContext.hasChanges {                 do {                     print("pre-save")                     try AppDelegate.appDelegate().persistentContainer.viewContext.save()                     print("post save")                 } catch {                     let nserror = error as NSError                     fatalError("Unresolved error \(nserror), \(nserror.userInfo)")                 }             }         }     } didChangeContent method     func controller(_ controller: NSFetchedResultsControllerNSFetchRequestResult, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {          print("didChangeContentWith")          guard let datasource = diffableDataSource else {             assertionFailure("The data source has not implemented snapshot support while it should")             return         }             datasource.apply(snapshot as NSDiffableDataSourceSnapshotInt, NSManagedObjectID, animatingDifferences: false)     } Cell Registration         let itemCellRegistration = UICollectionView.CellRegistrationPlaylistDetail2Cell, NSManagedObjectID { (cell, indexPath, itemId) in             guard let object = try? AppDelegate.appDelegate().persistentContainer.viewContext.existingObject(with: itemId) else {                 fatalError("Managed object should be available")             }             cell.playlistItem = object as! PlaylistItem             cell.playlistItemId = object.objectID         }
0
0
597
May ’21