Search code examples
swiftcore-datarx-swift

Problems with creating Observable when using @escaping closures


I am trying to code an observable for NSManagedObjectContext save() operation with no success. The function does not fire neither onNext nor onCompleted event and is being disposed immediately. When I debug with breakpoints it shows Disposables.create() and @escaping notification closure work on different threads. Please tell what am I doing wrong in the code below and help to fix the problem.

func save() -> Observable<Void> {
    guard base.hasChanges else { return Observable.just(()) }
    return Observable.create { observer -> Disposable in
        var token: NSObjectProtocol?
        token = NotificationCenter.default.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: self, queue: nil) { _ in
            observer.onNext(()) /* Is executed on the other thread and is never called */
            observer.onCompleted()
            NotificationCenter.default.removeObserver(token!)
        }
        
        base.perform {
            do {
                try base.save()
            } catch {
                observer.onError(Error.some)
            }
        }
        return Disposables.create() \* Immediately calls this func *\
    }
}

Solution

  • func save() -> Observable<Void> {
        guard base.hasChanges else { return Observable.just(()) }
        return Observable.create { observer -> Disposable in
            let queue = DispatchQueue(label: "Save")
            queue.sync {
                self.base.perform {
                    do {
                        try self.base.save()
                        observer.onNext(())
                        observer.onCompleted()
                    } catch {
                        observer.onError(NSManagedObjectContext.ReactiveError.save)
                    }
                }                
            }
            return Disposables.create()
        }
    }