BindableObjects 数组 SwiftUI
Array of BindableObjects SwiftUI
所以我正在尝试使用 SwiftUI 设置 CoreData,并且 CoreData 模型和 SwiftUI 视图都在工作。我需要做的就是连接它们。我能够传递离散数量的 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]
符合要求?
您可以使用实现 BindableObject 协议的 NSFetchedResultsControllerDelegate 并将更改转发到 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
上的实体
所以我正在尝试使用 SwiftUI 设置 CoreData,并且 CoreData 模型和 SwiftUI 视图都在工作。我需要做的就是连接它们。我能够传递离散数量的 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]
符合要求?
您可以使用实现 BindableObject 协议的 NSFetchedResultsControllerDelegate 并将更改转发到 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
上的实体