Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift — background task without freezing UI

I would like to do some heavy lifting in the background thread of my iOS app and NOT freeze the UI while it is being performed. What I try is:

self.someDisposable = heavyLiftingFuncReturningObservable()
            .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
            .observeOn(MainScheduler.instance)
            .subscribe(
                onNext: { [weak self] image in
                    // update UI
                },
                onError: { ... }
            )

Why does the above not work as expected and how to make it work?

like image 496
dobranoc Avatar asked Nov 09 '17 12:11

dobranoc


2 Answers

I believe the problem lies in your implementation of .heavyLiftingFuncReturningObservable(), namely in the fact that apparently it starts working on current thread instead of waiting until being subscribed to and running on background scheduler. Solution for that is to use .deferred() inside of .heavyLiftingFuncReturningObservable() function.

See http://adamborek.com/top-7-rxswift-mistakes/

like image 98
Maxim Volgin Avatar answered Nov 07 '22 08:11

Maxim Volgin


You can do this:

self.someDisposable = Observable.just(0) // dummy
    .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .flatMap { [unowned self] _ in
        heavyLiftingFuncReturningObservable()
    }
    .observeOn(MainScheduler.instance)
    .subscribe(
        onNext: { [weak self] image in
            // update UI
        },
        onError: { ... }
    )
like image 45
SoftDesigner Avatar answered Nov 07 '22 08:11

SoftDesigner