Массив BindableObjects SwiftUI - PullRequest
4 голосов
/ 04 июля 2019

Поэтому я пытаюсь настроить CoreData с помощью SwiftUI, и работают как модель CoreData, так и представления SwiftUI. Все, что мне нужно сделать, это подключить их. Я могу передать дискретное количество объектов BindableObject, но мне нужно передать массив. Вот настройки:

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))

, которая выдает следующую ошибку:

Метод экземпляра 'environmentObject' требует, чтобы '[Entry]' соответствовал 'BindableObject'

Как бы я сделал [Entry] соответствующим?

1 Ответ

1 голос
/ 07 июля 2019

Вы можете использовать NSFetchedResultsControllerDelegate, который реализует протокол BindableObject и передает изменения в 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

...