Custom RxSwift Extension Made Easy

Muhammad Muizzsuddin
2 min readMar 9, 2018

--

Please mail me if you find better English. I’ll love that!

I am about to create my own extension, that is my KeychainService to Rx world.

Here we go.

First I had this class KeychainService existed in my application. This class was to complex, a lot of thing changed if I rewrite it. Whilst some ideas come up, I found that the RxSwift has really simple way to expose our existing codebase to Reactive world. Thanks to those write this solution!

Introducing ReactiveCompatible protocol. That is a protocol which declare that our class is now compatible and exposable to Reactive world which served by RxSwift.

The protocol consist of generic type CompatibleType which declared as associatedtype. A simple reminder that associatedtype is the way we declare the protocol to be generic which means applicable to any conforming type.

Do you know where our UIButton object rx property comes from? Or you don’t remember that now URLSession class contains this property? Oh no!

The property comes from rx property of ReactiveCompatible protocol. The nice thing is you don’t have to implement this property since it’s default extension already implement this property.

Now lets make our hand more dirty.

I have a class KeychainService as mentioned above.

class KeychainService {
private let keychain: KeychainManager // This can be a library or your own private class
init(identifier: String) {
self.keychain = KeychainManager(for: identifier)
}
func set(key: String, value: String) throws {
// storing keychain logic can produce Error
}
func get(forKey: String) throws -> String? {
// getting keychain logic can produce Error
}
}

I don’t want to make a separate class to wrap KeychainService so make a Custom Extension is better solution.

extension KeychainService: ReactiveCompatible {}

See? I don’t need to implement the rx property. I just need to conform the protocol.

Now lets make wrapper methods for rx when it’s base is KeychainService.

extension Reactive where Base: KeychainService {
func set(key: String, value: String) -> Observable<Void> {
return Observable<Void>.create({(observer) -> Disposable in
do {
try self.base.set(key: key, value: value)
observer.onCompleted()
} catch let error {
observer.onError(error)
}
})
}
func get(forKey: String) -> Observable<String?> {
return Observable<Void>.create({(observer) -> Disposable in
do {
let value = try self.base.get(forKey: key)
observer.onNext(value)
observer.onCompleted()
} catch let error {
observer.onError(error)
}
})
}

Yups that’s all. Now KeychainSerice is exposable to Reactive world through its rx property. You have all the power of RxSwift now in your codebase!

If you find this article need to be updated, find some missing information, or need to polish its English, feel free to mail me at m.muizzsuddin @ gmail.com

--

--

Responses (2)