I'm creating simple messaging app based on CocoaAsyncSocket and STOMP protocol. So I created main class, which use PublishSubject
, so the subscribers can observe incoming STOMP frames, something like this:
class StompStream: NSObject {
//MARK: - Public
var inputFrame = PublishSubject<StompFrame>()
//MARK: - Private
fileprivate var socket: GCDAsyncSocket!
...
...
fileprivate func parse(withData data: Data) {
let string = String(data: data, encoding: .utf8)
do {
let frame = try StompFrame(text: string)
self.inputFrame.on(.next(frame))
} catch {
self.inputFrame.on(.error(error))
}
}
}
//MARK: - GCDAsyncSocketDelegate methods
extension StompStream: GCDAsyncSocketDelegate {
...
...
func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
self.parse(withData: data)
}
}
So, other who want to read inputFrame
, just do:
fileprivate func subscribeToEvents() {
self.stompStream.inputFrame
.observeOn(SerialDispatchQueueScheduler(queue: Queues().stompQueue, internalSerialQueueName: "stomp"))
.subscribe( onNext: { inputFrame in
//do some stuff
}).addDisposableTo(self.disposeBag)
}
I'm very new to RxSwift, and I read, that it's better to use Observable<StompFrame>
, if we want to just read the events, but with PublishSubject I can init it like this - PublishSubject<StompFrame>()
, and with Observable<StompFrame>
I couldn't understand how to do such thing, without creating some func
, where I will return Observable.create { }
, so every time if somebody will want to receive events, it will create another Observable<StompFrame>
, but with PublishSubject
it's only one.
Thanks for any help to explaining me this Rx stuff :)
Because the code is bridging from imperative to reactive world, here it makes sense to use a PublishSubject
under the hood.
A good practice is to make this subject private and only expose the Observable
to outside users.
class StompStream: NSObject {
var inputFrame: Observable<StompFrame> {
return inputFrameSubject.asObservable()
}
private let inputFrameSubject = PublishSubject<StompFrame>()
// ...
}
When in doubt about using a subject or not, I always refer to this post. Though written for C#, it is a great reference for this topic.