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
}
}
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags: