Last active
June 21, 2019 05:11
-
-
Save SlaunchaMan/045b0bd37ac68d1b7aacb5a6e88ed110 to your computer and use it in GitHub Desktop.
FetchPublisher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FetchPublisher.swift | |
// [REDACTED] | |
// | |
// Created by Jeff Kelley on 6/20/19. | |
// Copyright © 2019 Jeff Kelley. All rights reserved. | |
// | |
import CoreData | |
import Combine | |
@propertyDelegate | |
class FetchPublisher<PublisherType: Publisher, Entity>: NSObject, NSFetchedResultsControllerDelegate | |
where PublisherType.Output == Array<Entity>, Entity: NSManagedObject, PublisherType.Failure == Never { | |
private var controller: NSFetchedResultsController<PublisherType.Output.Element>? | |
private let publisher = PassthroughSubject<[Entity], PublisherType.Failure>() | |
private let fetchRequest: NSFetchRequest<Entity> | |
var value: PublisherType { return publisher.eraseToAnyPublisher() as! PublisherType } | |
init(_ entityType: PublisherType.Output.Element.Type, | |
sortDescriptors: [NSSortDescriptor]) { | |
fetchRequest = entityType.fetchRequest() as! NSFetchRequest<Entity> | |
fetchRequest.sortDescriptors = sortDescriptors | |
super.init() | |
} | |
func performFetch(_ context: NSManagedObjectContext) { | |
controller = NSFetchedResultsController( | |
fetchRequest: fetchRequest, | |
managedObjectContext: context, | |
sectionNameKeyPath: nil, | |
cacheName: Entity.entity().name) | |
controller?.delegate = self | |
do { | |
try controller?.performFetch() | |
} | |
catch { | |
fatalError(error.localizedDescription) | |
} | |
} | |
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { | |
publisher.send(controller.fetchedObjects as? PublisherType.Output ?? []) | |
} | |
var values: [Entity] { controller?.fetchedObjects ?? [] } | |
private var context: NSManagedObjectContext? { controller?.managedObjectContext } | |
public func delete(at indices: IndexSet) { | |
let values = self.values | |
indices.forEach { i in | |
context?.delete(values[i]) | |
} | |
} | |
} | |
typealias ManagedPublisher<T: NSManagedObject> = AnyPublisher<[T], Never> | |
typealias Fetched<T: NSManagedObject> = FetchPublisher<ManagedPublisher<T>, T> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment