You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:42:11