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
How to Use Socket in Swift (Connect, Send and Get Message)
Combined Chart (Line- and Bar Chart) Using iOS-Charts
Differenceand Purpose of Auto and Escaping Closure in Swift
Realm, Avoid to Store Some Property
Having Trouble with Nstimer (Swift)
How to Suppress a Specific Warning in Swift
Different Portrait/Landscape Views in Storyboard and Swift
Using a Metal Shader in Scenekit
Swift: Make Translucent Overlapping Lines of the Same Color Not Change Color When Intersecting
How to Make Sfspeechrecognizer Available on MACos
Loop Over Multiple Uialertcontroller'S
Swift Firebase Custom Object with Document Id
Swift Extension Storage for Protocols
Symbol Is Considered to Be an Identifier, Not an Operator
Getting a Segmentation Fault: 11 with Swift 5.2 When Using Filemanager.Default.Currentdirectorypath