SwiftUI 将 CoreDate 连接到设置 window (macOS)

SwiftUI connect CoreDate to settings window (macOS)

我最近在我的应用程序中添加了一个设置窗格,并尝试将其连接到核心数据,让用户管理他们的 api 和 url 设置。
但不幸的是,当我启动我的应用程序并打开设置面板时,我总是会收到一堆错误,告诉我核心数据没有正确连接或类似的东西。 - 以下错误消息
--------------------------------------

这是我的 App.swift 文件,我在其中添加了设置窗格。

@main
struct RandomAppName: App {
    
    let persistenceController = PersistenceController.shared
    @State private var filter = 1
    
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
         
        }
       .commands { // some command features }
                
        
        
        #if os(macOS)
        
                Settings {
                    SettingsPane()
                        .environment(\.managedObjectContext, persistenceController.container.viewContext)
                     }
        
                #endif
        
        
        }
        }

设置窗格本身包含一个带有多个子视图的选项卡视图。
这里有一些代码片段。

import SwiftUI

struct SettingsPane: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @State private var id : Int = 3

 var body: some View {

// some content stuff //

  if id == 1 || id == 0 {  ApiView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)  }

// some content stuff //

}
}

和一些实际的 Api 设置视图

import SwiftUI

struct ApiView: View {

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \APIMaster.timestamp, ascending: true)],
        animation: .default)
    private var content: FetchedResults<APIMaster>

   var body: some View {

    // some content stuff //

        VStack{

          ScrollView{
          ForEach(content,  id: \.self) { content in

            HStack{
             Image(systemName: "xserve")
             Text(content.hostName)
             }

            }}

    // some content stuff //
 

} }


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


在我实现核心数据部分之前,一切都运行良好。
我已经在应用程序视图中用核心数据连接测试了 ForEach 循环,它工作得很好。

错误信息是:

2021-01-09 21:28:11.348566+0100 RandomAppName[71835:2714021] [错误] 警告:多个 NSEntityDescriptions 声明 NSManagedObject 子类 'APIMaster' 因此 +entity 无法消除歧义。 CoreData:警告:多个 NSEntityDescriptions 声明了 NSManagedObject 子类 'APIMaster' 所以 +entity 无法消除歧义。
2021-01-09 21:28:11.348698+0100 RandomAppName[71835:2714021] [错误] 警告:'APIMaster' (0x600003128000) 来自 NSManagedObjectModel (0x600002530230) 声明 'APIMaster'。 CoreData:警告:来自 NSManagedObjectModel (0x600002530230) 的 'APIMaster' (0x600003128000) 声明 'APIMaster'。

我希望有人能帮我解决这个具体问题。

这是设置窗格的样子。 (我也尝试了“主要”实体)

我终于找到了一个非常简单的方法来解决我的问题。
以下代码在 Xcode 12.3.
中非常适合我 要访问 PersistenceController.shared,我们需要将我们的视图连接到在 App 文件中调用的“main”PersistenceController.shared。

@main
struct RandomAppName: App {

let persistenceController = PersistenceController.shared
@State private var filter = 1


var body: some Scene {
    WindowGroup {
        ContentView()
            .environment(\.managedObjectContext, persistenceController.container.viewContext)
     
    }
   .commands { // some command features }
            
    
    
    #if os(macOS)
    
            Settings {
                SettingsPane(viewContext: persistenceController.container.viewContext)
                    .environment(\.managedObjectContext, persistenceController.container.viewContext)
                 }
    
            #endif
    
    
    }
    }

在设置 window 中,我们要求这样的持久性:

import SwiftUI

struct SettingsPane: View {
    
   let viewContext : NSManagedObjectContext // ask for the persistence

    @State private var id : Int = 3

 var body: some View {

// some content stuff //

  if id == 1 || id == 0 {  ApiView(viewContext: viewContext)  } // pass the persistence to the subview

// some content stuff //

}
}

子视图中的结局:

import SwiftUI

struct ApiView: View {

 let viewContext : NSManagedObjectContext // ask for the persistence

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \APIMaster.timestamp, ascending: true)],
        animation: .default)
    private var content: FetchedResults<APIMaster>

   var body: some View {

    // some content stuff //

        VStack{

          ScrollView{
          ForEach(content,  id: \.self) { content in

            HStack{
             Image(systemName: "xserve")
             Text(content.hostName)
             }

            }}

    // some content stuff //
 



  } }
    
   // I just uncomment the PreviewProvider because it's not necessary for me 
   // struct ApiView_Previews: PreviewProvider {
   //     static var previews: some View {
   //          ApiView()
   //     }
   //  }

这对我来说很好用(我不知道这是不是官方的方式)
希望能帮到有同样问题的人。