Updating View With Two Data Sources in iOS

In this article I am going to describe a robust, simple and clean app architecture that allows to update a single iOS tableView from two different data sources asynchronously.

Let’s say, we have two sources of data, that need to be displayed in a tableView. When user pulls to refresh a tableView, two separate asynchronous requests are performed. While updating continues we need to show activity indicator and we can dismiss it only when both requests are finished.

This can be cleanly accomplished using ReactiveCocoa + MVVM. One of the benefits of ReactiveCocoa is in the easiness of synchronization of asynchronous data streams.

One would say, that this task can be also performed by using of dispatch groups. I agree, but it is more complex and not easy to do when the nature of data sources is different. For example, when one of the datasources is HTTP API and the second is a WebSocket.

Architecture looks like this:

In a ViewModel we have 3 arrays – cloudData1 (or any other name you want, that better describes your domain), cloudData2 and a union single datasource of a TableView – tableData. When cloudData1 or cloudData2 updates, the update of tableData is triggered and then it triggers an update of the TableView itself by bindings.

In the init method of a ViewModel we create a binding of cloudData1 and cloudData2 to tableData:

Also we combine two flags of progress cloud1RequestInProgress and cloud2RequestInProgress to a single one – inProgress.

LoadData method of a ViewModel starts the loading of data from each of two datasources:

And in a TableView we create a binding between ViewModels tableData and a View:

Pull to refresh triggers loadData of a ViewModel:

In a view we also create a binding between inProgress property of a ViewModel and the need to dismiss refreshing indicator:

Simple and brief -> easy to support, extend and reuse.

Почему нужно писать юнит-тесты, пример

Юнит тесты реально спасают, я вот написал тест:

и он не прошел. Оказалось, что я забыл проставить boolValue тут:

Что интересно, без boolValue никаких warnings и тем более ошибок сборки.

iOS Unit Test Examples / Snippets

In this article I will post common iOS Unit testing examples for testing of:

  1. Asynchronous loading of data using REST API
  2. Loading of a UIView
  3. Method call after UITableViewCell is clicked
  4. Static UITableView sections have correct number of rows
  5. Loading of a UIView from UIStoryboard
  6. IBOutlet connection
  7. Model logic
  8. UITableViewCell subclass
  9. IBAction / Method is implemented
  10. Testing bundle name

Asynchronous loading of data using REST API

Here [RSHTTPClient sharedClient] is an instance of AFHTTPSessionManager subclass. But it doesn’t matter, the main is the principle.

Loading of a UIView

Method call after UITableViewCell is clicked

Here we verify that method restoreHomeKitClicked is called when user selects a specific row in UITableView.

Static UITableView sections have correct number of rows

Loading of a UIView from UIStoryboard

IBOutlet connection

Model logic

Here we test that an array, that is formed inside our model has correct number of items. Model logic testing obviously can be different depending of logic itself.

UITableViewCell subclass

IBAction / Method is implemented

Testing bundle name

The last is a rare case, but helps to prevent someone changing a bundle name of project accidentally.

How to wait until several AFNetworking requests finish

Use dispatch_group_t, dispatch_group_enter dispatch_group_leave, dispatch_group_notify.

Also, below is code to send a huge array to server by dividing ti to parts. It is actual when a single request is too big for server – you get “URL too long error” or HTTP 414.

How to create semi-transparent outside border for UIImageView

Just in case if somebody looks for an UIImage with transparent outside border. If you simply set a layer border, you will get a transparent border, but you will see inside image behind that border, not outside image. I managed to create an ImageView with transparent outside border.

It looks like this:
cool image

The idea is simple. I save UIImage from UIImageView. Then I remove UIImage and set initial layer as border layer. Then I put a new smaller sublayer above it and set a saved UIImage as contents of it.

The same approach can be used for UIButton or UIView.

Способ разогнать Android Studio

Может кому будет полезно – способ разогнать Android Studio. У меня он дико тормозил из-за сложного layout и большого размера проекта. Кроме этого, на аймаке нет SSD.

Нужно увеличить размер памяти для виртуальной Java-машины. Я увеличил у себя до 2 Гб. Все стало летать.

Создаем так конфиг и внутри пишем:

Причина тормозов – прожорливость Java в плане памяти.

Здесь подробнее.

Snippet to determine a size of control in Android

It is a common task to get a control size. You may need it to create image assets to customize that control.

First we get a control object, for example ToggleButton. Then we get a pixel density of the device. After that we can convert px units to dp units.

Язык программирования Go

Посоветовали обратить внимание на этот язык программирования Go.

Выглядит с первого взгляда как некий апгрейд языка C с добавлением garbage collection, type safety, dynamic typing, variable length arrays, key-value maps, large standard library. Нет наследования как в C++, но есть композиция и интерфейсы. Более быстрая компиляция, чем в C++ и лучше поддержка многопоточности.