RxSwift Part 5 (RxCocoa)

https://techblog.vn/rxswift-and-rxcocoa

This is the continuation of previous part 4. In this part we will cover RxCocoa

  1. UITextField in Rx way
  2. Use case of throttle operator
  3. Why RxCocoa
  4. UIButton in Rx way
  5. Use Case of combineLatest operator
  6. Use Case of share(replay:) operator
  7. UITableView in Rx way
  8. API Request in Rx way

RxSwift → is a framework for interacting with the Swift programming language, in a reactive manner

RxCocoa → is a framework that makes Cocoa APIs used in iOS and OS X easier to use with reactive techniques
OR
RxCocoa provide wrapper to Cocoa API’s to adopt reactive environment

UITextField

As shown in Figure 1 we subscribed to UITextField using RxCocoa

Few things to note

  1. By calling rx, you access the RxCocoa extensions for the relevant class. In this case, it’s a UITextField. (UITextField+Rx.swift)
  2. .text return the the contents of the text field as an Observable value. text is another RxCocoa extension, This is the same property UITextField already has but in this extension you can subscribe to it. So when User enter any text in the UITextField it update text property and you will get the value inn subscription block
  3. observeOn → It allows you to change the scheduler on which the observer code will be executed. We will discuss this in detail later
  4. throttle since user can typing so fast and passing to subscriber for every key press could be computationally expensive and lead to a lagging UI. In part3 We discussed throttle and debounce in detail
  5. notNilValue operator we created in part3. This will filter nil and unwrap the optional value . There is a same operator in RxSwift extension called unwrap
Figure 1

As shown in Figure 2 we are validating password field and returning whether user enter password according to the rules defined.

Figure 2

You can add many operators in between to obtain what you want as I added filter operator to notified my subscriber when user pass our rules. We can chain functions, meaning that each function takes the result of the previous function but it should return Observable sequence that can be observe

Figure 3

Why RxCocoa

So, the question is What is the need of UITextField reactive things if they have a textChange delegate method that also is reactive and the answer is

  1. There are some different ways to pass information from one object to another in iOS reactively (Notification, pass in closure, delegate, KVO, & target/action,) each of these different systems may be simple by itself but most of the complexity in the logic of an iOS app is in having to convert from one of these systems to another. RxSwift/RxCocoa replaces virtually all of these systems with one which is in a Rx way.
  2. To compatible with RxSwift stuff and to easily work with Rxswift Observable things. Like UITextField return Observable same like RxSwift so that you can use RxSwift operators and whole it’s API
  3. To used all of your RxSwift skills in Cocoa API’s as well

UIButton

Few things to note

  1. By calling rx, you access the RxCocoa extensions for the relevant class. In this case, it’s a UIButton. (UIButton+Rx)
  2. .tap Reactive wrapper for `TouchUpInside` control event. It return the Observable sequence where you can apply Rx operators tools according to your case. This is one of the reason we have RxCocoa
  3. .bind subscribes an element handler to an observable sequence that is return after filtered from throttle operator

What If we want when if userName is not empty and password field is valid than change login Button color as shown in Figure 5

As shown in Figure 4 we did this. There . are few things to be note

  1. Clear debugging information for new developer , Let’s say new developer want to understand all the login button logic he only need to see this method and it works. In imperative programming he need to search all its usage in the controller
  2. validUserName observer will first get the unwrap text from UITextField for every 0.5 sec and check if its valid and there is a change in the validation output then it send to all subscriber and same for . validPasswordName
  3. Loginbutton combining both userName and password textField latest value and associates color logic on this. part3 We discussed combineLatest in detail
Figure 4
Figure 5

As shown in Figure 6 everythingValid observable created twice. Remember in part 3 we said create method gets executed as many times as we subscribe. In this case . we are binding twice which is same as subscription. One button for color logic and second for button interaction state. So how we solve it

Figure 6

As shown in figure 7 wee used share(replay:1) which create a single observable that is share between all subscription . In part 3 we discussed this operator in detail

Figure 7

Same for validUserName observable . First time it create when we called validUserName.subscribe and second time when Observable.combineLatest(validUserName, validPasswordName) is called. The solution is same as above

Figure 8

Add share(replay:1) to validPasswordName and validUserName will solve this

Figure 9

UITableView

There are few things to be noted

  1. As discussed in part 1 we need dispose subscription to avoid memory leak using DisposeBag. DisposeBag is a bag (or collection) of disposables. when you subscribe to any observables you add disposables to this bag Because of adding the Disposable into the DisposeBag it means the DisposeBag have a strong reference to Disposable, since the bag is the controller property and when the view controller is deallocated, its variables (including the bag) are deallocated. When the disposeBag is deallocated, its deinit function calls dispose on all of the disposables it contains
  2. users variable contains BehaviorRelay observable sequence. BehaviorRelay we disccussed detail in part 2. “A BehaviorRelay wraps a Behavior Subject.What makes it different from Behavior Subject is that it never terminated means you can’t call completed,error or dispose method on observable subject and you can ask it for its current value without subscribing to receive updates which is very helpful”
  3. We fetched all users from Github and store in users variable by using accept method in BehaviorRelay which will immediately emit data to all it’s subscriber
  4. Called bind(to:) to associate the users observable with the code that executes each row in the table view.
  5. By calling rx, you access the RxCocoa extensions for the relevant class. In this case, it’s a UITableView. (UITableView+Rx.swift)
  6. Pass in a block for each new item. This is the same as cellForRow method and added this subscription to the disposable bag
  7. RxCocoa adds to UITableView called modelSelected(_:). This returns an Observable you can use to watch information about selected model objects. Reactive wrapper for delegate message tableView:didSelectRowAtIndexPath
Figure 10

Our fetchdata is not reactive let’s make it Reactive. Let’s discuss line by line

  1. send method return Observable sequence<T> where T should conformed to Codable protocol. We used Single Observable sequence. A Single is a variation of Observable that, instead of emitting a series of elements, is always guaranteed to emit either a .success or an .error. as discussed in Part 2
  2. fetchData first create urlRequest , then call api and and onSuccess assign data to users observable
Figure 11

Useful Links

Senior iOS Engineer | HungerStation | Delivery Hero