People often talk about reactive programming, and RxSwift in particular, as the ultimate way to describe application logic — event chaining, error handling, asynchrony. But don’t forget, RxSwift is also a tool in its own right, allowing you to add reactive extensions to anything.

RxSwift has a large and creative community. There are currently 55 repositories of varying sizes and purposes in RxSwiftCommunity ‘s github repository. Their roots are in reactive programming.

Next I’ll talk about the must-have dependencies in my Podfile.

RxKeyboard

We all love overlapping password fields with our keyboards, don’t we?

I don’t want to count the lines of code or describe NotificationCenterhow disgusted I am with using . Just look at how cool it is to express changes in keyboard height through the concept of sequence of events. Let me remind you that all Rx operators are provided here. You can use it here debounce, or in Observablecombination with another, etc. Here is my favorite example of declarative code:

RxKeyboard.instance.isHidden
  .drive(backgroundFadeView.rx.isHidden)
  .disposed(by: disposeBag)

I can explain it, when the keyboard is hidden, I hide it backgroundFadeView; when the keyboard is visible, I show it backgroundFadeView. Although you can see it at a glance.

RxGesture

This situation is very common when UIButtonthere is not enough. Let’s compare the syntax:

...

I can explain again, we only filter .endedthe gestures and calculate the translation. But even if you’re not familiar with the framework or RxSwift, this is obvious.

The problem with this old Cocoa pattern is that the code is spread out across all classes. To find out what’s going on with the view, you have to dig through the entire class and find the code that actually should be in one place. you need to:

  • Write callback function;
  • create GestureRecognizer;
  • configure it (set maximum number of touches maximumNumberOfTouches);
  • Add it to the view;

The first item is the scariest. The class will have a function passed to #selector(). Is this a real function? No, this is a callback function with a name for no reason. This function must be anonymous (such as a closure) to restrict developers from calling it manually.

Util functions like setupGestureRecognizerthis also have the same problem, because the component’s setup code is placed here. These functions are not really functions. They do not express the behavior of the class. We just need to separate the code in some way “to improve its readability”. At the same time, the size of the class increases, the meaning becomes less clear, and the real business logic becomes complex and difficult to understand.

With RxGesture, all your code (creation, configuration, callbacks) is in one place. You can quickly view and modify them. There aren’t any pointless utility functions that are the result of a futile attempt to keep code separated.

RxDataSources

How about the most concise part of dealing with the most important thing in every iOS developer’s life ( UITableViewUICollectionView)? Such an important problem requires a lot of code.

We have code spread throughout the class, and delegates, and completely useless numbersOfRowInSectionand numberOfSectionsmethods. Sections should be expressed using language tools, such as generic structures SectionModel <String, Int>, which require a section name and an array of section elements. Now, the number of sections and cells can be inferred implicitly. The length of the array is always equal to the number of sections, and the length of the nested array is equal to the number of cells in the section.

And there is no need to IndexPathaccess the items in the array. Keep it simple. The closure below configureCelltakes the model as a parameter. The programmer simply creates a cell from it.

There is an added bonus – the diff algorithm, which works in O(N) complexity. We will go into details in the next article. Just emit a new partial array and the framework will update only where needed. No more calls are needed reloadData. Additionally, animation updates and convenient closures are supported out of the box instead of deprecated delegates. For me, using a footer activity indicator in a collectionView has never been more convenient.

RxSwiftExt

RxSwift implements the reactiveX.io specification but is not very open to new ideas. But this does not hinder the development of the community, hence the custom operator library . They’re all very small and simple, but they help me avoid writing dozens of lines of code every day.

If you already have experience using Rx, you may be interested in best error handling practices. Some would suggest using the Railway pattern and Resulttype instead of onNextthe onErrorindispensable callback system.

My favorite method is to split the sequence of events into a sequence of errors and a sequence of elements. With this approach, there is no chance that any observable will complete or fail with an error unless you want it to.

I recommend you read more about handling RxSwift errors with Materialize here .

RxFlow

A great framework for handling navigation problems in a passive way . An article about it will be published soon, if you don’t want to miss it, please follow me 🙂

It’s easy to see that reactive frameworks combine similar syntax and motivations. People want to reduce the amount of code without reducing readability. RxSwift uses asynchronous event working methods to really allow you to do this. You only need one line of code, whereas an imperative style might require ten lines of code.

I highly recommend browsing the other libraries in RxSwiftCommunity. You’ll find reactive extensions for many iOS widgets, as well as a variety of architectures including unidirectional data flow. It’s always useful to know other ways to solve everyday tasks. Maybe they’ll be better than yours?

If you like this story, please like and share it to help others find it! Feel free to leave a message below. Follow me to learn more about RxSwift.

Leave a Reply

Your email address will not be published. Required fields are marked *