'Passing ManagedObject collection from fetch result to closure up to ViewController

I want to perform a background fetch and pass the result to closure. Currently I'm using performBackgroundTask method from NSPersistentContainer which is giving a NSManagedObjectContext as a closure. Then using that context I'm executing fetch request. When fetch is done I'm, passing the result to the completion handler.

func getAllWorkspacesAsync(completion: @escaping ([Workspace]) -> Void) {
    CoreDataStack.shared.databaseContainer.performBackgroundTask { childContext in
        let workspacesFetchRequest: NSFetchRequest<Workspace> = NSFetchRequest(entityName: "Workspace")
        workspacesFetchRequest.predicate = NSPredicate(format: "remoteId == %@", "\(UserDefaults.lastSelectedWorkspaceId))")
        do {
            let workspaces: [Workspace] = try childContext.fetch(workspacesFetchRequest)
            completion(workspaces)
        } catch let error as NSError {
            // Handle error
        }
    }
}

I'm going to call this method from ViewModel and use Combine PassthroughSubject to notify the ViewController about the event.

class WorkspaceViewModel {

    private var cancellables: Set<AnyCancellable> = []
    let resultPassthroughObject: PassthroughSubject<[Workspace], Error> = PassthroughSubject()

    private let cacheManager = WorkspaceCacheProvider.shared

    static public let shared: WorkspaceViewModel = {
        let instance = WorkspaceViewModel()
        return instance
    }()

    func fetchWorkspaces() {
        cacheManager.getAllWorkspacesAsync { [weak self] workspaces in
            guard let self = self else { return }
            self.resultPassthroughObject.send(workspaces)
        }
    }
}

And the ViewController code:

class WorkspaceViewController: UIViewController {

    private var cancellables: Set<AnyCancellable> = []

    override func viewDidLoad() {
        super.viewDidLoad()
    
        WorkspaceViewModel.shared.resultPassthroughObject
            .receive(on: RunLoop.main)
            .sink { _ in } receiveValue: { workspaces in
            // update the UI
        }
        .store(in: &cancellables)

    }
}

My question is: is it safe to pass NSManagedObject items?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source