@environmentkey的核心数据结果

发布于 2025-02-08 08:27:36 字数 4399 浏览 0 评论 0原文

我尝试从如何重新使用相同的fetchrequest,而不是在几个视图中使用相同的请求?

我在@main中构建了带有核心数据的简单应用程序,

//  Count+CoreDataProperties.swift

extension Count {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Count> {
        return NSFetchRequest<Count>(entityName: "Count")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var name: String?
    @NSManaged public var number: Int16

}

    //  CoreDataManager.swift // all structs to fetch core data and set Environment
  
    public struct CountEnvironmentKey: EnvironmentKey {
        public static var defaultValue: [Count] = []
    }
    
    public extension EnvironmentValues {
        var counts: [Count] {
            get { self[CountEnvironmentKey.self] }
            set { self[CountEnvironmentKey.self] = newValue }
        }
    }
    
    public extension View {
        func setCount(_ counts: [Count]) -> some View {
            environment(\.counts,  counts)
        }
    }
    
    struct CountLoaderViewModifier: ViewModifier {
        @FetchRequest( sortDescriptors: [])
        var counts: FetchedResults<Count>
        
        func body(content: Content) -> some View {
            content
                .setCount(Array(counts))
        }
    }
    
    extension View {
        func loadCounts() -> some View {
            modifier(CountLoaderViewModifier())
        }
    }


//  ContentView.swift


struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @Environment(\.counts) var counts

    var body: some View {
        NavigationView {
            List {
                ForEach(counts) { item in
                    NavigationLink {
                        Text("\(item.number)")
                    } label: {
                        Text("Item at \(item.name!)")
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }

    }

    private func addItem() {
        withAnimation {
            let newItem = Count(context: viewContext)
            newItem.name = "Name"
            newItem.number = 1
            newItem.id = UUID()

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { counts[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

//  MyEnvApp.swift


@main
struct MyEnvApp: App {
    
    let persistenceController = PersistenceController.shared


    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
               .loadCounts()
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

我会收到警告 环境中的上下文未连接到持久的商店协调器:&lt; nsmanagedObjectContext:0x60000273dfb0&gt; 样本中的代码 @ObseverObject var persistenceManager = persistenceManager(usage:.main) 还会产生错误,我知道我需要将核心数据存储连接到环境,

感谢提前的帮助

i try to adopt answer from How to re-use the same FetchRequest, rather than the same request in several views?

i build simple app with Core data

//  Count+CoreDataProperties.swift

extension Count {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Count> {
        return NSFetchRequest<Count>(entityName: "Count")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var name: String?
    @NSManaged public var number: Int16

}

    //  CoreDataManager.swift // all structs to fetch core data and set Environment
  
    public struct CountEnvironmentKey: EnvironmentKey {
        public static var defaultValue: [Count] = []
    }
    
    public extension EnvironmentValues {
        var counts: [Count] {
            get { self[CountEnvironmentKey.self] }
            set { self[CountEnvironmentKey.self] = newValue }
        }
    }
    
    public extension View {
        func setCount(_ counts: [Count]) -> some View {
            environment(\.counts,  counts)
        }
    }
    
    struct CountLoaderViewModifier: ViewModifier {
        @FetchRequest( sortDescriptors: [])
        var counts: FetchedResults<Count>
        
        func body(content: Content) -> some View {
            content
                .setCount(Array(counts))
        }
    }
    
    extension View {
        func loadCounts() -> some View {
            modifier(CountLoaderViewModifier())
        }
    }


//  ContentView.swift


struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @Environment(\.counts) var counts

    var body: some View {
        NavigationView {
            List {
                ForEach(counts) { item in
                    NavigationLink {
                        Text("\(item.number)")
                    } label: {
                        Text("Item at \(item.name!)")
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }

    }

    private func addItem() {
        withAnimation {
            let newItem = Count(context: viewContext)
            newItem.name = "Name"
            newItem.number = 1
            newItem.id = UUID()

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { counts[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

//  MyEnvApp.swift


@main
struct MyEnvApp: App {
    
    let persistenceController = PersistenceController.shared


    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
               .loadCounts()
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

in @main i getting warning
Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x60000273dfb0>
the code from sample
@ObservedObject var persistenceManager = PersistenceManager(usage: .main)
generate error also, i understand that i need to connect my core data store to environment

thanks for help in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧街凉风 2025-02-15 08:27:37

.loadCounts()被用作外部(之后)的修饰符,该修饰符设置了环境中的托管对象上下文。这意味着环境价值不存在于您的修饰符体内。尝试移动.loadCounts()上面的.environment(\。托管ObjectContext,...)

.loadCounts() is applied as a modifier outside (after) the modifier that sets the managed object context in the environment. This means the environment value is not present in your modifier's body. Try moving .loadCounts() above .environment(\.managedObjectContext, ...).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文