Build a Foursquare clone iOS app — Part 4: Streaming location

Content

Introduction

In this part, we will continue the implementation of UserLocationService class, which has the responsibility of obtaining and transmitting the user location.

The ReactiveX API will be used for this transmission, allowing us to exercise reactive skills and also write more readable tests.

Basic ReactiveX

I’d like first to give a (really) simple introduction to this great library, so you can understand what the code will do in this article and its main concepts.

The two concepts I’d like to focus are:

  • Data streams: think of another way of transmitting data (an array, or a string) between two classes or structs. One way could be through a parameter in a public method or through the NSNotificationCenter to broadcast this data. Using the ReactiveX library you can wrap up any data in another class called Observable which gives you powerful operators to manipulate it.
  • Observer pattern: the instance that wants to receive the data has to subscribe to the instance that sends the data.

Then using these two concepts, the modification we need to do with UserLocationService class are:

  1. Wrap the native location object CLLocation received by CLLocationManager to become an Observable<CLLocation> .
  2. Allow another class or struct to subscribe to UserLocationService class to receive the Observable<CLLocation> whenever this data is available.

Streaming user location

To achieve item 1 above, we will use specifically the provided type Subject . By quoting the official documentation:

It can pass through the items it observes by reemitting them, and it can also emit new items.

Which means we can use a Subject as a proxy to receive the CLLocation and also send to its Observer .

To achieve item 2, we will add an internal method called getUserLocation to expose the Subject instance.

Given this, we write the next code iteration of UserLocationService after the Part 2 of this series of articles:

Note the type cast in the getUserLocation method return

Cover with tests

Fortunately, the way we designed the application so far gives us the opportunity to test this last feature. By injecting a protocol into UserLocationService constructor, we can easily mock the location obtained by the device.

These are the new cases I have elaborated:

  • The location provided by CLLocationManager class should be the same provided then by UserLocationService .
  • If CLLocationManager fails somehow, this error should be passed through UserLocationService class to be handled at UI.

Now translating to code:

Please note some refactor was done since last article, specially to move the dependencies resolutions to the setUp method. Check the Github repository for full source and check all the tests written for UserLocationService class.

Conclusion

We could learn some basics concepts of ReactiveX, and how we can use this tool to transform a native API into a reactive paradigm. Not forgetting also to ensure the logic of the app is working by writing tests.

Now that we have the user location, in the next step we will learn how to make a HTTP request to fetch the nearby places for this location.

Next part: Network layer