I've just updated to Xcode 16 and started receiving warnings that AnyHashable is marked not Sendable. The majority of my app uses tableviews with UITableViewDiffableDataSource<Int, AnyHashable>, since diffable now needs AnyHashable and Sendable separately, this has caused a tonne of small issues. I am using a custom lightweight MVVM protocol that requires the ViewModel to return a datasource of this type, so that it can be made generic, standardised and easily adapt to any situation. Code can be reused fairly easily, VC or any other class needs to know nothing about the internals. This has made a lot of the UI/business logic extremely flexible.
Now i'm trying to find a solution with the least amount of refactoring. My options seem to be to create my own AnyHashableSendable, which i've discovered can't receive the same "magic" as AnyHashable, requiring updating a 1000 references to either use someStruct.base and wrap array appends in .init(SomeStruct(...)), update array mutating functions, etc.
Or the other option is to make each implementation of diffable explicitly state its type. Which removes a layer of flexibility that I'm relying on.
To me, this change has just dramatically increased the complexity of building a simple app that doesn't rely on much concurrency. Supplying an array of items into a tableview now requires secondary objects/handling, and has me questioning moving to diffable instead of a previous attempt to build my own datasource handler that just took in a 2d array.
Does anyone have a better solution that doesn't needlessly make the app more complex? Should we have added (or can we now) an AnyHashableSendable that receives the same compiler magic as AnyHashable? Any thoughts/help would be appreciated
Another approach would be to use a Hashable + Sendable custom enum type that covers the different cases you want to represent instead of AnyHashable for the identifier.
Similar to what I was playing around with. Downside with this approach, compared to the inbuilt AnyHashable, is that If I have an array that I want to append to. E.g.
let data: [AnyHashableSendable] = []
data.append(SomeStruct(...))
I now have to wrap SomeStruct with an init of the new wrapper AnyHashableSendable(SomeStruct(...))
Likewise, when extracting it I can't cast the wrapper itself, I have to extract the wrappedValue
let item = data[0]
let castItem = item.wrappedValue as? SomeStruct
This is all achievable obviously, just a pain in the ass to simply have a generic list for DiffableDataSource
Thats exactly what i'm trying to avoid. The content in my app is very dynamic, and changing frequently (we are doing a lot of research trying to figure out what users want). I'm really looking for the ability to just say "There will always be an array of things" and check them when needed. Rather than having to keep building/editing layers to define what might be in the list. Just seems overkill and unnecessary