Search code examples
swiftrx-swift

Force-unwrapping dispose bag while using RxSwift


I want to use RxSwift but alwo don't want to force-unwrap.

When I use [weak self] I get the error that self must be unwrapped - ie. self can't be optional in this case

public func getPages() -> Observable<[(String, String)]> {
    return Observable.create {
        [weak self] observer -> Disposable in
        if let pages = self?.pages {
            observer.onNext(pages)
        } else {
            self?.allPages()
                .debug()
                .subscribe({ event in
                    switch event {
                    case .next(let dta):
                        observer.onNext(dta)
                    case .error(let error):
                        observer.onError(error)
                    case .completed:
                        break
                    }
                }).disposed(by: self.disposeBag)
        }
        return Disposables.create()
    }
}

my solution has been to force-unwrap self at that point, however this is not right.

i.e.

}).disposed(by: self!.disposeBag)

So how can I avoid force-unwrapping in this case?


Solution

  • The code presented is all kinds of wrong... If I understand what you are trying to do, a simple share is all you need:

    let getPages = allPages()
        .share(replay: 1)
    

    Once you subscribed to getPages, the share operator will cache the emission and replay it to every other observer that subscribes to it.

    Otherwise, notice that you are supposed to return a disposable from the create closure. You are generating a disposable when you call subscribe and then putting one in the dispose bag instead of returning it. Instead, do something like this:

    func getPages() -> Observable<[(String, String)]> {
        return Observable.create { [weak self] observer in
            guard let this = self else {
                observer.onCompleted()
                return Disposables.create()
            }
            guard let pages = this.pages else {
                return this.allPages()
                    .subscribe(observer)
            }
            observer.onNext(pages)
            observer.onCompleted()
            return Disposables.create()
        }
    }
    
    • If self doesn't exist by the time the observable is subscribed to, then just complete.
    • If self exists, but pages doesn't, then call allPages() and bind it to the observer.
    • Otherwise, emit pages and complete.