Skip to content

Instantly share code, notes, and snippets.

@SlaunchaMan
Last active June 21, 2019 05:11
Show Gist options
  • Save SlaunchaMan/045b0bd37ac68d1b7aacb5a6e88ed110 to your computer and use it in GitHub Desktop.
Save SlaunchaMan/045b0bd37ac68d1b7aacb5a6e88ed110 to your computer and use it in GitHub Desktop.
FetchPublisher
//
// 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