Build a Foursquare clone iOS app — Part 4: Streaming location
Content
- Part 1: Introduction and setup
- Part 2: Location data and managing dependencies
- Part 3: Continuous Integration
- Part 4: Streaming location
- Part 5: Network layer
- Part 6: State management
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 calledObservable
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:
- Wrap the native location object
CLLocation
received byCLLocationManager
to become anObservable<CLLocation>
. - Allow another class or struct to subscribe to
UserLocationService
class to receive theObservable<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:
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 byUserLocationService
. - If
CLLocationManager
fails somehow, this error should be passed throughUserLocationService
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.