【问题标题】:SwiftUI connect CoreDate to settings window (macOS)SwiftUI 将 CoreDate 连接到设置窗口(macOS)
【发布时间】:2021-04-15 06:14:09
【问题描述】:

我最近在我的应用中添加了一个设置窗格,并尝试将其连接到核心数据以让用户管理他们的 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
        
        
        }
        }

设置面板本身包含一个带有多个子视图的选项卡视图。
这里有一些代码sn-ps。

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] [error] 警告:多个 NSEntityDescriptions 声明 NSManagedObject 子类“APIMaster”,因此 +entity 无法消除歧义。 CoreData:警告:多个 NSEntityDescriptions 声明 NSManagedObject 子类“APIMaster”,因此 +entity 无法消除歧义。
2021-01-09 21:28:11.348698+0100 RandomAppName[71835:2714021] [错误] 警告:来自 NSManagedObjectModel (0x600002530230) 的“APIMaster”(0x600003128000) 声称“APIMaster”。 CoreData:警告:来自 NSManagedObjectModel (0x600002530230) 的“APIMaster”(0x600003128000) 声明“APIMaster”。

我希望有人可以帮助我解决这个具体问题。

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

【问题讨论】:

标签: macos core-data swiftui swift5


【解决方案1】:

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

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

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()
   //     }
   //  }

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

【讨论】:

    猜你喜欢
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    • 2021-03-27
    • 2021-07-24
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多