1

Background:

I have complex Swift Data models with some Relationships, and at some point, my Xcode Preview is no longer working when I want to init a ModelContainer in it. So I tried to debug and create a simple file with no dependencies with other parts of my project.

Here's my simple code:

import Foundation
import SwiftUI
import SwiftData
struct DebugView: View {
 var body: some View {
 Text("Hello")
 }
}
@Model
class User {
 var name: String
 init(name: String) {
 self.name = name
 }
}
#Preview {
 let config = ModelConfiguration(UUID().uuidString, isStoredInMemoryOnly: true)
 let container = try! ModelContainer(for: User.self, configurations: config) // This line failed
 DebugView()
}

The thing is even this simple view cannot be shown in the Preview window. Error message:

enter image description here

I'm sure that the crash line is at the ModelContainer init because it works fine without it.

I tried to delete the cache data with command:

xcrun simctl --set previews delete all

But it's still not working.

The weird thing is, when I created a new project and move all the files in it, it works at the beginning. But it started to failed when I tried to do some modifications on other files (these simple codes stay unchanged).

Does any one have any idea?

asked Dec 24 at 16:54
1
  • 1
    Pretty sure nowadays the app template shows you how to use preview traits to configure the preview model container Commented Dec 24 at 18:15

1 Answer 1

0

Preview needs to be provided data just like you would at "App" level when you start the app on Simulator or on Device.

The best way to provide mock data for preview is using PreviewModifier

Here is a sample SwiftData Modifier

struct SwiftDataPreview: PreviewModifier {
 //All the Model types
 static let types: [any PersistentModel.Type] = [Item.self]
 //Make mock/sample context
 static func makeSharedContext() async throws -> Context {
 let schema = Schema(types)
 //In Memory Context
 let config = ModelConfiguration(isStoredInMemoryOnly: true)
 let contailer = try ModelContainer(for: schema, configurations: config)
 let context = ModelContext(contailer)
 
 //Make any samples
 
 for n in (0...10) {
 let item = Item(timestamp: .now + TimeInterval(n))
 context.insert(item)
 }
 return context
 }
 
 typealias Context = ModelContext
 
 func body(content: Content, context: Context) -> some View {
 content
 .modelContext(context)
 }
}
//Helper so you can access with dot notation
extension PreviewTrait where T == Preview.ViewTraits {
 @MainActor static var swiftDataInMemory: Self = .modifier(SwiftDataPreview())
}

Then you can use it with

#Preview(traits: .swiftDataInMemory) {
 ContentView()
}
answered Dec 25 at 16:13
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. I tried this but still it didn't work. I suspect that this abnormal crash is not related to the code, but rather it's environment problems.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.