【问题标题】:SwiftUI PreviewProvider using CoreData to show specific NSManagedObject EntrySwiftUI PreviewProvider 使用 CoreData 显示特定的 NSManagedObject 条目
【发布时间】:2021-12-28 01:44:30
【问题描述】:

[Xcode 12.4、Catalina 10.15.6、使用 SwiftUI 和 CoreData 的 MacOS 项目]

我正在开发一个应用程序来显示我拥有的一些数据。该应用程序的业务逻辑运行良好,现在我将注意力转向了 UI。 为了整理 UI,我想让 PreviewProvider 为每个视图工作。我还希望预览显示我在 CoreData 数据存储中已有的数据。

经过一番挫折,我终于设法编译和显示预览,但是我在预览中没有看到任何实际数据。看起来,虽然 NSManagedObjectContext 在那里,但预览没有选择任何要显示的条目。

我如何选择数据存储中的第三个条目以显示在预览中?

下面是我的视图代码,其中包含末尾的PreviewProvider(正常情况下),下面是一些 cmets 解释它。

    
    
    import SwiftUI
    
    struct DomainRow: View {
      
      @Environment(\.managedObjectContext) var context
      @ObservedObject var domain : DomainFiles
      private var id : LocalizedStringKey {
        get {
          return LocalizedStringKey(String(Int(domain.id)))
        }
      }
      
      var body: some View {
        HStack (alignment: .center) {
          Text(id)
          Spacer()
          VStack(alignment: .leading) {
            Text(domain.name!)
              .fontWeight(.bold)
              .truncationMode(.tail)
              .frame(minWidth: 20)
    
            Text(domain.path!)
              .font(.caption)
              .opacity(0.625)
              .truncationMode(.middle)
          }
        }
        .padding(.vertical, 4)
      }
    }
    
    #if DEBUG
    struct DomainRow_Previews: PreviewProvider {
    
      @Environment(\.managedObjectContext) var managedObjectContext
    
      static var previews: some View {
        let context = CoreDataStack.context
        let domain = DomainFiles(context: context)
        return DomainRow(domain: domain)
          .environment(\.managedObjectContext, CoreDataStack.context)
      }
    }
    #endif

DomainFiles 是一个 CoreData 实体(有几千个条目),每个实体都有几个属性,包括 idnamepath(到文件)。 CoreDataStack.context 是对如下所示结构的引用。

为了根据 PreviewProvider 的要求获得静态 NSManagedObjectContext,我已将以下结构添加到我的项目中,根据 https://developer.apple.com/forums/thread/650269

    import Foundation
    import CoreData
    
    struct CoreDataStack {
        static var context: NSManagedObjectContext {
            return persistentContainer.viewContext
        }
      
        static let containerName: String = "MyAppsDataStore"
    
        static var persistentContainer: NSPersistentContainer = {
            let container = NSPersistentContainer(name: containerName)
            container.loadPersistentStores { (description, error) in
                if let error = error {
                    print(error)
                }
            }
            return container
        }()
    //    Don't need to save anything in the preview.
    //    func saveContext() { ... }
    }

例如,我想将带有domain.id == 3 的条目传递到预览中。 我怎样才能做到这一点? (提前感谢您的关注。)

【问题讨论】:

    标签: core-data swiftui


    【解决方案1】:

    我找出了我的 PreviewProvider 结构中缺少的内容:

    1. 我需要执行 NSFetchrequest 才能获取数据。
    2. 然后,我可以使用数组索引访问数据存储中的条目。
      请注意,索引是 CoreData 内部表示,如果您想要特定的项目,请使用 SQLite 浏览数据存储区以找到您想要查看的那个。
    struct EntriesView_Previews: PreviewProvider {
    
      @Environment(\.managedObjectContext) var managedObjectContext
    
      static var previews: some View {
        let context = CoreDataStack.context
        let domainFiles : [DomainFiles]
        let requestDomainFiles : NSFetchRequest<DomainFiles> = DomainFiles.fetchRequest()
        do {
          domainFiles = try context.fetch(requestDomainFiles)
        } catch {
          let nserror = error as NSError
          fatalError("Error \(nserror): \(nserror.userInfo)")   //  DO NOT DO THIS IN REAL CODE.  PROVIDE FALLBACK
        }
        let domain = domainFiles[0]
        return EntriesView(domain: domain)
          .environment(\.managedObjectContext, CoreDataStack.context)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2020-11-23
      相关资源
      最近更新 更多