SwiftData预览报错:无法找到Habit类的活跃容器求助
问题分析
这个预览报错的核心原因是:你直接初始化的SampleGoals里的Goal和Habit实例不属于预览容器的上下文,当ModifyGoalView里对这些实例执行SwiftData相关操作时,系统找不到绑定Habit的容器,因此抛出错误。另外你的模型关联定义也不符合SwiftData的要求,加剧了这个问题。
解决方案
1. 修正模型关联定义
SwiftData需要通过@Relationship来管理模型间的关联,不能用简单的let数组替换。修改Goal模型:
@Model class Goal: Identifiable { var name: String @Attribute(.unique) let id: String // 用@Relationship声明关联,设置删除规则为级联,同时改为var让SwiftData管理 @Relationship(deleteRule: .cascade) var habits: [Habit] init(name: String, id: String, habits: [Habit] = []) { self.name = name self.habits = habits self.id = id } }
2. 在预览容器上下文内创建测试数据
不要再用外部的SampleGoals预初始化实例,而是直接在预览容器的上下文里创建数据,确保所有模型实例都属于当前容器:
@MainActor let previewContainer: ModelContainer = { do { let config = ModelConfiguration(for: Goal.self, Habit.self, isStoredInMemoryOnly: true) let container = try ModelContainer(for: Goal.self, Habit.self, configurations: config) let context = container.mainContext // 直接在容器上下文内创建Habit和Goal实例 let habit1 = Habit(name: "Comprehensible input", id: "dsafda", frequency: .daily) let habit2 = Habit(name: "Study Grammar", id: "djsakfdhjska", frequency: .weekly) let goal1 = Goal(name: "Spanish B2", id: "dasfdsa", habits: [habit1, habit2]) let habit3 = Habit(name: "Habit name", id: "dsafe", frequency: .daily) let goal2 = Goal(name: "Goal 2", id: "ashdjskaf", habits: [habit3]) // 将实例插入上下文并保存 context.insert(goal1) context.insert(goal2) try context.save() return container } catch { fatalError("Failed to create container: \(error.localizedDescription)") } }()
3. 从预览容器上下文获取实例用于预览
预览时不要直接用外部实例,而是从容器的上下文中查询获取:
#Preview { do { let context = previewContainer.mainContext let fetchDescriptor = FetchDescriptor<Goal>() let goals = try context.fetch(fetchDescriptor) guard let firstGoal = goals.first else { fatalError("No test goals found in preview container") } return ModifyGoalView( modifyType: .edit, modifyGoalPresented: .constant(true), goal: firstGoal) .modelContainer(previewContainer) } catch { return Text("Failed to load preview: \(error.localizedDescription)") } }
额外注意事项
- 清理项目Derived Data,重启Xcode后再尝试预览
- 确保
ModifyGoalView中对goal的处理符合SwiftData规范(比如用@Bindable修饰传入的Goal实例)
内容的提问来源于stack exchange,提问作者Taylor Hartman
相关产品推荐
相关产品推荐

