17

I'm a newbie in RxSwift and need a very basic help.
Assump that I have an Observable and subscribe it like this.

 let source: Observable<Void> = Observable.create { [weak self] observer in

        guard let _ = self else {
            observer.on(.Completed)
            return NopDisposable.instance
        }

        observer.on(.Next())

        return AnonymousDisposable {

        }
    }

And the subscribe like this:

 source.subscribeNext { () -> Void in

    }

The question is: how can I emit the event to subscribeNext manually every time I need. This is like rx_tap behavior on UIButton.
I see in the example code has something like this source = button.rx_tap.asObservale(). After that, every time user tap to button, there will emit an event and trigger on subscribeNext(). I also want to have that behavior but in programmatically, not from UI event.

dummy307
  • 193
  • 1
  • 2
  • 6

2 Answers2

19

Most of the time, you can compose your observable and the solution I'm about to give is not the recommended way to do Rx code.

You can look at Subject to implement the behavior you request. There are multiple variations on subject, that the documentation explains well.

An example usage, inspired from RxSwift's playground:

let subject = PublishSubject<String>()

_ = subject.subscribeNext { content in
    print(content)
}
subject.on(.Next("a"))
subject.on(.Next("b"))

This will print "a" then "b".

For more detail about when to use subject or not, I'd recommend reading this article.

tomahh
  • 13,441
  • 3
  • 49
  • 70
  • 1
    Hi @tomahh, Your solution works. However, what is reason you mentioned it as 'not the recommended way'? And how about when compare it with ```AnyObserver```.
    With ```AnyObserver<>```, we can use it like:
    `var beginLoad: AnyObserver?` `beginLoad = AnyObserver(eventHandler: { (event) -> Void in print("1234543") })` `beginLoad.on(.Next())`
    – dummy307 Mar 17 '16 at 01:46
  • Also that ```PublishSubject()``` is not a ```Observable```, so we can't using operators on it (flatten, concat....). – dummy307 Mar 17 '16 at 02:40
  • 2
    You can call `asObservable()` on the subject to get it as an `Observable`. – tomahh Mar 17 '16 at 08:05
  • Subjects are most often used to wrap imperative APIs. You'd usually compose upon already existing observables (rx_tap being a good example). I'd recommend reading [this article](http://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx), though not in swift, that goes a long way into explaining when to use Subject. – tomahh Mar 17 '16 at 08:07
  • Yes, I see the way how to subject emit an event. Thanks a lot @tomahh. The remaining is learn to choose correct type of subject to use :). – dummy307 Mar 17 '16 at 16:12
  • Just to simplify, you can call the method like this: `subject.onNext("b")` – Seeler99 Jul 20 '17 at 17:42
1

For a Driver, you can do

var isSearching: Driver<Bool>

isSearching = Driver.just(true)
Maria
  • 4,471
  • 1
  • 25
  • 26