ReactiveSwift Extension

Written by aren.ankit | Published 2018/03/28
Tech Story Tags: reactive-programming | reactiveswift | reactive | swift | reactiveswift-extension

TLDRvia the TL;DR App

Adding more support on Binding operator (<~)

I have experimented with different app architecture pattern recently and decided to work with MVVM with FRP and used ReactiveCocoa/ReactiveSwift for that.

As usual i required some helper methods and want to add some missing methods in reactive for my usage and decided to add them to extension.

This Article assumed you are experienced with ReactiveCocoa/ReactiveSwift and if you are not, i advised you to go and understand basic concept first.

Lets go through that extension and the helps it provides.

1. Custom Bindings:

We may have used following reactive way to update some properties on UIView.

let showView = MutableProperty(false)

self.view.reactive.isHidden <~ self.viewModel.showView

This simply generates binding between `BindingTargetProvider` and `BindingSource`.`showView` is a simple mutableProperty in here.

What this code does is update `isHidden` property of view depending on showView mutableProperty Changes.

So far so good, this just shows the default behaviour of this binding.

By going through Reactive Struct definition, we can see that it is a proxy to hosts reactive extensions of Base which means we need to extend this to add more reactive bindings.

/// A proxy which hosts reactive extensions of `Base`.

public struct Reactive<Base> {

/// The `Base` instance the extensions would be invoked with.

public let base: Base

}

Now what we want is to add some more binding if not available:Firstly we will add method that will generate bindings.

Add Method in Reactive Extension to make custom bindings.

Lets see how to use this with an example of *loaderToggling* on UIView depending on some mutableProperty.

We will extend Reactive When Base: UIView as loader toggling will be done only on UIView instances.

As you can see this function generates binding that will toggle loader based on showLoader property which will come from mutableProperty.

Custom binding created for UIView show loader

After setting bindings, this can be used as any other bindings

self.disposable += self.view.reactive.showLoader <~ self.viewModel.buyNowAction.isExecuting

self.disposable += self.view.reactive.showLoader <~ self.viewModel.showLoader.producer

Below you can see another example of adding reactive property on custom Class FloatingLabelTextField

2. Allowing Optional in **<~** bindings:

We all have used this operator <~ as seen above this is to bind `BindingTargetProvider` and `BindingSource` if you go through the definition, you could see that it allow Source.Value to be optional but not the BindingTargetProvider value.

Lets see what this means.

self.containerView.reactive.isHidden <~ self.viewModel.showView

In above statement view can not be optional. In case you happen to have view to be optional you will get following error:

But you may be asking we tend to have view to be `forceUnwrapped` since its always retain by superView.

Firstly its possible to be using above operator on other classes than UIView retained by superview.

In my case i was working with an project with multiple target which has multiple storyboard but same controller class which required me to have IBOutlet to be optional.

Lets append this operator for optional target support:

self.containerView?.reactive.isHidden <~? self.viewModel.showView

Now this will work and we will be able to use optional view like shown above.

Gonna raise this as amendment in ReactiveSwift soon so its possible to have this inbuilt in future version of ReactiveSwift and no need to use the extension, but till then .. feel free to include this in your code.

Gist for above can be found in here. It’s all in one file for portability.Use it as you like.

You can go through my other articles as well:

Thank you for reading!

Open for your comments on the comment section, if you have any questions, or have any thing to share.


Published by HackerNoon on 2018/03/28