Forked from josephlord/FetchedResultsControllerPublisher.swift
Created
January 7, 2022 20:46
-
-
Save seanlilmateus/83476c7222bc36555b54e2ce299f2d14 to your computer and use it in GitHub Desktop.
Making a Combine publisher from a FetchedResultsController
This file contains hidden or 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
// | |
// FetchedResultsControllerPublisher.swift | |
// ListsModel | |
// | |
// Created by Joseph Lord on 09/06/2019. | |
// Copyright © 2019 Joseph Lord. All rights reserved. | |
// | |
import Foundation | |
import Combine | |
import CoreData | |
/// Create by passing in a FetchedResultsController | |
/// This will perform the fetch request on the correct queue and publish the resutls on the | |
/// publishers. | |
final public class FetchedResultsControllerPublisher<FetchType> | |
where FetchType : NSFetchRequestResult { | |
private let internalFRCP: FetchedResultsControllerPublisherInternal<FetchType> | |
/// Pass in a configured fetchResults controller and this class will provide a choice of publishers | |
/// for you depending on how you like your errors | |
public init(fetchedResultsController: NSFetchedResultsController<FetchType>, | |
performFetchNotRequired: Bool = false) { | |
self.internalFRCP = FetchedResultsControllerPublisherInternal( | |
fetchedResultsController: fetchedResultsController, | |
performFetch: !performFetchNotRequired) | |
} | |
public lazy var publisherWithErrors: AnyPublisher<[FetchType], Error> = { | |
return self.internalFRCP.publisher.eraseToAnyPublisher() | |
}() | |
public lazy var publisher: AnyPublisher<[FetchType], Never> = { | |
return self.internalFRCP.publisher.replaceError(with: []).eraseToAnyPublisher() | |
}() | |
} | |
final private class FetchedResultsControllerPublisherInternal<FetchType> | |
: NSObject, NSFetchedResultsControllerDelegate | |
where FetchType : NSFetchRequestResult { | |
let publisher: PassthroughSubject<[FetchType], Error> | |
let fetchedResultsController: NSFetchedResultsController<FetchType> | |
init(fetchedResultsController: NSFetchedResultsController<FetchType>, | |
performFetch: Bool) { | |
self.fetchedResultsController = fetchedResultsController | |
publisher = PassthroughSubject<[FetchType], Error>() | |
super.init() | |
fetchedResultsController.delegate = self | |
fetchedResultsController.managedObjectContext.perform { | |
do { | |
if performFetch { | |
try fetchedResultsController.performFetch() | |
} | |
self.publisher.send(fetchedResultsController.fetchedObjects ?? []) | |
} catch { | |
self.publisher.send(completion: .failure(error)) | |
} | |
} | |
} | |
@objc func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { | |
publisher.send(fetchedResultsController.fetchedObjects ?? []) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment