Post

Replies

Boosts

Views

Activity

Reply to SortDescriptor from a generic method crashes Xcode Previews but not Simulator.
Thank you for your time replying. Yeah I had many problems a year or two ago in getting the container right. But I think it ok at the moment especially as it works fine creating a SortDescriptor one way, but creating it the other way (without changing anything else) causes the crash. I copied only the necessary code to a basic app today so the whole thing fits in here. There are actually 2 files with previews and they add the model container in different ways: .modelContainer(PreviewDataController.previewContainer) .modelContainer(for: Item.self, inMemory: true) So the problem is probably else where. import SwiftData @main struct MyAppApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ Item.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } import SwiftData struct ContentView: View { @Query private var items: [Item] var body: some View { NavigationView{ ItemsList(sortStyle: .alphabetical) } } } #Preview { ContentView() .modelContainer(for: Item.self, inMemory: true) } import SwiftUI import SwiftData struct ItemsList: View { @Environment(\.modelContext) private var modelContext @Query private var items:[Item] = [] init(sortStyle:ListSortingStyle<Item> = .alphabetical) { let sortDescriptor1 = SortDescriptor<Item>(\.name, comparator: .localized, order: .forward) //this works in both let sortDescriptor2 = sortStyle.sortDescriptor() //this works in simulator but not in preview print(sortDescriptor1,"\n",sortDescriptor2) let fetchDescriptor = FetchDescriptor<Item>(sortBy:[sortDescriptor1]) // <-- change between 1&2 to reproduce the crash self._items = Query(fetchDescriptor) } var body: some View { List { ForEach(items) { item in NavigationLink { Text(item.name) } label: { Text("\(item.name)") } } } .toolbar { ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } private func addItem() { withAnimation { let newItem = Item(name: "New Item") modelContext.insert(newItem) } } } #Preview { NavigationView{ ItemsList(sortStyle: .alphabetical) .modelContainer(PreviewDataController.previewContainer) } } import Foundation import SwiftData @MainActor class PreviewDataController { static let previewContainer: ModelContainer = { do { let schema = Schema([ Item.self, ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true) let container = try ModelContainer(for: schema, configurations: [modelConfiguration]) return container } catch { fatalError("Failed to create container for preview: \(error.localizedDescription)") } }() /// A Protocol for models to help get predicates etc to sort protocol ListSorting { var name:String {get} } extension Item:ListSorting {} enum ListSortingStyle<T>:String,CaseIterable where T:ListSorting { case alphabetical = "A…Z" case alphabeticalReverse = "Z…A" /// Returns a SortDescriptor matching the case func sortDescriptor() -> SortDescriptor<T> { switch self { case .alphabetical: SortDescriptor<T>(\.name, comparator: .localized, order: .forward) case .alphabeticalReverse: SortDescriptor<T>(\.name, comparator: .localized, order: .reverse) } } } import Foundation import SwiftData @Model final class Item { var name:String = "" init(name: String) { self.name = name } }
Mar ’25