I attempted to create a SortDescriptor using a method in enum to sort various different models in SwiftUI lists. But it causes crashes in Xcodes previews but not in the simulator, and I don't know why. Maybe someone could suggest changes.
extension Item:ListSorting {} //List sorting is a protocol given to various Models enum ListSortingStyle<T>:String,CaseIterable where T:ListSorting { case alphabetical = "A…Z" case alphabeticalReverse = "Z…A" case createDate = "Newest" case createDateReverse = "Oldest" case editDate = "Latest Edit" case editDateReverse = "Oldest Edit" /// Returns a SortDescriptor matching the enumeration func sortDescriptor() -> SortDescriptor<T> { switch self { case .alphabetical: SortDescriptor<T>(\.name, comparator: .localized, order: .forward) case .alphabeticalReverse: SortDescriptor<T>(\.name, comparator: .localized, order: .reverse) case .createDate: SortDescriptor<T>(\.creationDate, order: .forward) case .createDateReverse: SortDescriptor<T>(\.creationDate, order: .reverse) case .editDate: SortDescriptor<T>(\.editDate, order: .forward) case .editDateReverse: SortDescriptor<T>(\.editDate, order: .reverse) } } }
Which is used in
struct ItemsList: View { @Environment(\.modelContext) private var modelContext @Query private var items:[Item] = [] init(sortStyle:ListSortingStyle<Item> = .alphabetical) { let sortDescriptor = SortDescriptor<Item>(\.name, comparator: .localized, order: .forward) //(1) This works in preview & simulator //OR let sortDescriptor2 = sortStyle.sortDescriptor() //(2) This crashes in a preview when used in a fetch not in the iOS simulator print(sortDescriptor,sortDescriptor2) let descriptor = FetchDescriptor<Item>(sortBy:[sortDescriptor2]) self._items = Query(descriptor) } var body: some View { ... } }
As far as I can see both methods create a SortDiscriptor. If I print the sortDescriptor variable in they look almost identical:
//1 SortDescriptor<Item>( order: Foundation.SortOrder.forward, keyString: nil, comparison: Foundation.SortDescriptor<MyApp.Item>.AllowedComparison.comparableString( (extension in Foundation):Swift.String.StandardComparator(options: __C.NSStringCompareOptions(rawValue: 0), isLocalized: true, order: Foundation.SortOrder.forward), \Item. <computed 0x0000000340213b18 (String)>) ) //2 SortDescriptor<Item>( order: Foundation.SortOrder.forward, keyString: nil, comparison: Foundation.SortDescriptor<MyApp.Item>.AllowedComparison.comparableString( (extension in Foundation):Swift.String.StandardComparator(options: __C.NSStringCompareOptions(rawValue: 0), isLocalized: true, order: Foundation.SortOrder.forward), \Item.<computed 0x0000000340022174 (String)>) )
But the one created with the generic method on the enum crashes with the error message:
CrashReportError: Fatal Error in DataUtilities.swift MyApp crashed due to fatalError in DataUtilities.swift at line 64. Couldn't find \Item.<computed 0x0000000340022174 (String)> on Item with fields [SwiftData.Schema.PropertyMetadata ...