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

使用CoreData保存数据后跳转至其他视图的实现方案求助

问题分析与解决方案

首先,你遇到的Thread 1: "executeFetchRequest:error: A fetch request must have an entity."错误和导航组件本身无关,是SetView中Core Data的Fetch Request配置错误导致的——要么是创建FetchRequest时没指定实体,要么是实体名称和Data Model中的定义不匹配。先解决这个Core Data问题,再用iOS 16+推荐的导航方式实现跳转。

一、先修复Core Data错误

检查SetView中的FetchRequest代码:

  • 错误示例(未指定实体):
    @FetchRequest() var cards: FetchedResults<Card>
    
  • 正确写法(指定实体+排序规则):
    // 方式1:显式指定实体
    @FetchRequest(entity: Card.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Card.term, ascending: true)])
    var cards: FetchedResults<Card>
    
    // 方式2:使用Xcode自动生成的实体类,更简洁
    @FetchRequest(sortDescriptors: [SortDescriptor(\.term)]) var cards: FetchedResults<Card>
    

同时确保:

  1. 实体类名(比如Card)和Data Model文件中的实体名称完全一致(大小写敏感);
  2. SetView已通过环境变量获取正确的上下文:
    @Environment(\.managedObjectContext) private var viewContext
    

二、iOS 16+ 导航实现方案

方案1:使用navigationDestination修饰符(推荐)

这是iOS 16+官方推荐的导航方式,替代旧版NavigationLink(isActive:):

NavigationStack {
    List {
        ForEach(viewModel.termdefpairs.indices, id: \.self) { index in
            TermView(term: $viewModel.termdefpairs[index].term,
                     definition: $viewModel.termdefpairs[index].definition,
                     tag: $viewModel.termdefpairs[index].tag)
        }
    }
    .navigationBarItems(trailing: Button(action: {
        // 保存数据到Core Data
        for testForm in viewModel.termdefpairs {
            dataController.add(term: testForm.term, name: name, definition: testForm.definition, tag: testForm.tag, context: managedObjectContext)
        }
        // 触发跳转
        isShowingSet = true
        // 若当前视图是弹出的sheet,保留dismiss();否则可移除
        // dismiss()
    }) {
        Text("Save")
    })
    // 绑定导航触发状态,指定目标视图
    .navigationDestination(isPresented: $isShowingSet) {
        SetView()
    }
}

方案2:传递数据的导航(适合需要给SetView传参的场景)

如果需要把保存后的闪卡集合数据直接传递给SetView,可以用navigationDestination(for:):

  1. 先定义可哈希的模型(用于导航标识):

    struct FlashcardSet: Hashable {
        var name: String
        var cards: [TermDefPair] // 你的术语-定义配对模型
    }
    
  2. 在当前视图中实现:

    @State private var selectedSet: FlashcardSet?
    
    NavigationStack {
        List {
            ForEach(viewModel.termdefpairs.indices, id: \.self) { index in
                TermView(term: $viewModel.termdefpairs[index].term,
                         definition: $viewModel.termdefpairs[index].definition,
                         tag: $viewModel.termdefpairs[index].tag)
            }
        }
        .navigationBarItems(trailing: Button(action: {
            // 创建闪卡集合模型
            let newSet = FlashcardSet(name: name, cards: viewModel.termdefpairs)
            // 保存到Core Data
            for testForm in viewModel.termdefpairs {
                dataController.add(term: testForm.term, name: name, definition: testForm.definition, tag: testForm.tag, context: managedObjectContext)
            }
            // 触发跳转并传递数据
            selectedSet = newSet
        }) {
            Text("Save")
        })
        // 指定接收FlashcardSet类型的导航目标
        .navigationDestination(for: FlashcardSet.self) { set in
            SetView(selectedSet: set)
        }
    }
    
  3. 在SetView中接收参数:

    struct SetView: View {
        let selectedSet: FlashcardSet
        @Environment(\.managedObjectContext) private var viewContext
        // ... 视图代码
    }
    

内容的提问来源于stack exchange,提问作者syphixy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 14:56:37