swift - BindableObjects 数组 SwiftUI

标签 swift core-data protocols swiftui

所以我正在尝试使用 SwiftUI 设置 CoreData,并且 CoreData 模型和 SwiftUI View 都在工作。我需要做的就是连接它们。我能够传递离散数量的 BindableObjects 但我需要的是传递一个数组。这是设置:

let peristence = PersistenceManager()
var model = [Entry]() // Entry Conforms to NSManagedObject and BindableObject
let request = Entry.createFetchRequest()
let sort = NSSortDescriptor(key: "callsign", ascending: true)
request.sortDescriptors = [sort]
do {
    model = try peristence.persistenceContainer.viewContext.fetch(request)
} catch {
    fatalError(error.localizedDescription)
}

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(model))

这会产生以下错误:

Instance method 'environmentObject' requires that '[Entry]' conform to 'BindableObject'

我如何使 [Entry] 符合要求?

最佳答案

您可以使用 NSFetchedResultsControllerDelegate 实现 BindableObject 协议(protocol)并将更改转发到 NSFetchedResultsController

class BindableFetchedResults<ResultType>: NSObject, BindableObject, NSFetchedResultsControllerDelegate where ResultType : NSFetchRequestResult {

    let controller: NSFetchedResultsController<ResultType>
    var results: [ResultType]? {
        controller.fetchedObjects
    }
    let didChange = PassthroughSubject<Void, Never>()

    init?(fetchRequest: NSFetchRequest<ResultType>, managedObjectContext context: NSManagedObjectContext) {
        self.controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        super.init()
        self.controller.delegate = self
        do {
            try controller.performFetch()
        } catch {
            return nil
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        didChange.send()
    }
}

在代码中,是这样的:


let persistence = PersistenceManager()
let request = Entry.createFetchRequest()
let sort = NSSortDescriptor(key: "callsign", ascending: true)
request.sortDescriptors = [sort]

guard let model =  BindableFetchedResults(fetchRequest: request, managedObjectContext: persistence.persistenceContainer.viewContext) else {
    fatalError()
}

if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(model))

然后您可以访问 model.results 上的实体

关于swift - BindableObjects 数组 SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56888087/

相关文章:

ios - swift 数组 : subscript with IndexPath - unable to mutate

swift - 指示tableView的indexPath何时为最后一个

ios - 其他文件中的ViewController

swift - 使用可选的完成处理程序调用自身进行迭代,不会第二次完成

ios - 在 Objective C 中使用 iOS 在 CoreData 中创建与属性的关系

ios - 如何: Using Combine to react to CoreData changes in the background

url - URL 中的方案和协议(protocol)有什么区别?

ios - CoreData并发和释放对象

postgresql - 通过 psql 在 postgresql 中执行 postgres 扩展查询

arrays - 如何使类型化数组符合协议(protocol)