How to Detect If a Observable Has Not Emitted Any Events for Specific Time in Rxswift

How to : Detect if a observable has not emitted any events for specific time in RxSwift

Doing some documentation research I found rxSwift's onError: handler.

This will fire off upon receiving an errorEvent, from there I can run a function
onError: {err in errorAlert(); print("error \(err)")} That solves the problem.

Receive events of an Observable from a point of time in Rx

There's no such thing as "events before I subscribed" because an Observable doesn't start emitting events until after it's been subscribed to.

For example look at the create function.

let obs = Observable.create { observer in 
// do stuff to observer
return Disposables.create()
}

That closure being passed into the create function is called every time the observable is subscribed to. In other words, each subscription gets its own series of events and each of them start from a fresh execution of the closure. There were no "events before the subscription happens."

All of the above is for the default "cold" observable. There is also the notion of "hot" observables (like Subjects) that share their events among all the subscribers, but they don't store old events unless you explicitly use one that is designed to do so.

So the solution to your problem is not to look for a hack, but instead to use the proper tool for the job.


UPDATE

Regarding your comment about using BehaviorSubject. The simple solution is to just not use it if you don't need its functionality. Use a PublishSubject instead. Another solution is to use .skip(1) to avoid getting the currently held value.

Handling circular style events on observable sequence RxSwift

Your helper function updateIndividualObservables(:) triggers an event every time you update which in turn triggers the combineLatest you implemented above.

I would suggest you to keep a State object instead

struct TermsAndConditionState {
var terms: Bool
var privacy: Bool
var marketing: Bool
var acceptAll: Bool
}

In updateIndividualObservables method change this state and implement this state change with your respective checkboxes

func render(state: TermsAndConditionState) {
if state.acceptAll {
// TODO: update all checkboxes
} else {
// TODO: update individual checkboxes
}
}

Which RxSwift operator to use for uniquely emitted elements and how to?

You should add the distinctUntilChanged operator:

location.distinctUntilChanged { $0.speed < 25 && $1.speed < 25 }
.debounce(.seconds(20), scheduler: MainScheduler.instance)
.filter { $0.speed < 25 }
.subscribe(onNext: { location in
print(location)
})
.disposed(by: disposeBag)

EDIT
Case when location should be printed every 20 seconds if speed is less than 25:

let isSpeedBelow = location
.distinctUntilChanged { $0.speed < 25 && $1.speed < 25 }
.flatMapLatest { location -> Observable<Double> in
if location.speed >= 25 {
return Observable.just(location)
}
return Observable<Int>.timer(.seconds(10), period: nil, scheduler: MainScheduler.instance)
.map { _ in location.speed }
}
.map { $0 < 25 }
.startWith(true)

Observable<Int>.timer(.seconds(10), period: .seconds(10), scheduler: MainScheduler.instance)
.withLatestFrom(isSpeedBelow)
.filter { $0 }
.withLatestFrom(location)
.subscribe(onNext: { location in
print(location)
})
.disposed(by: disposeBag)

Create an observable that emits all values so far

You can use the scan operator, where the accumulator is an array, and the closure adds on element to it on every new event.

http://introtorx.com/Content/v1.0.10621.0/07_Aggregation.html#Scan

However this is quite strange, and would really quickly become get really slow and crazy, if you're not careful.

Returning observable using if/else statement is not working with RxSwift flatMap

Swift compiler usually has a hard time inferring types, especially with complex frameworks such as RxSwift. You can (and usually should) help the compiler by explicitly stating your intent and declaring the return type for the closure, e.g.:

let a = Observable.of(1)
let b = Observable.of(2)
var test = true
let c: Observable<Int> = Observable.of(3).flatMap { _ -> Observable<Int> in
if test {
return a
} else {
return b
}
}

How to put delay in RxSwift?

You can use Observable.timer along with Observable.zip.

Something like:

Observable<MyType>.zip(
myObservable,
Observable<Int>.timer(RxTimeInterval.seconds(5), scheduler: MainScheduler.instance),
resultSelector: { myItem, _ in return myItem }
)

Result selector is to ignore value produced by timer.



Related Topics



Leave a reply



Submit