In just about every single app you’re going to make there’s going to be networking. We work with it so much that it becomes 2nd nature after a while. The great thing about RxSwift is that it makes networking a breeze, especially when parsing your models from JSON.

In this example we’re going to assume you’ve got a View Model that handles your networking with a connect() method. I’ll provide a link to one of my Gists from my Udemy Course that will provide us with some JSON to work with.

Observables and Subscriptions

When you create an observable, you define its behaviour. The thing is an observable exists to be observed and when you do that we have issues with memory. That is why, weird as it may seem, we have to return a disposable when we create an observable. This will give us a chance to cancel what we’re doing, which is especially handy when working with networking.

Singles

Singles are more specific observables that return a value or an error which is perfect in our scenario where the json will return or an error will. It does using a handy success/error enum with pattern matching.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
func connect() -> Single<String> {
   
    return Single<String>.create(subscribe: { single in
       
        let url = "https://gist.githubusercontent.com/isaacmendez/9ef13dfe10f668c2cd433ec1d99f92bc/raw/cd6c72578caa1ba0c4376af40813f1a995ab580e/inspringQuotesDataModel.json"
       
        Observable.from([url])
            .map {
                let url = URL(string: $0)!
                return URLRequest(url: url)
            }
            .flatMap { request in
                URLSession.shared.rx.response(request: request)
            }
            .subscribe(onNext: { [weak self] response, data in
                guard let json = try? JSONDecoder().decode([[String: String]].self, from: data) else {
                   
                        single(.error(URLError.couldNotPullData))
                   
                        return
                }

                let newTitle = json[0]["quote"] ?? "Y'all go no quotes"
               
                single(.success(newTitle))
            }).disposed(by: self?.disposeBag)
       
        return Disposables.create()
    })
}

We start by making an observable of type String – we’re basically going to return a string to display and subscribe to it’s changes. I’ve left out using Codeble just now as it’s easy enough to simply define the object you want in the decode method and it keeps it simpler.

We have to return a disposable at the end and we could have done some tidying up there as well. This is called when the subscription is done with the observable.

First we make an array of URLs and map over it returning a URL Request, then we use flatMap which basically will get all of the responses from the request after it’s called and reduce it into one observable sequence. We subscribe to the changes and decode the data just like working with standard JSON decoding and finally dispose of the subscription using our handy dispose bag.

As you can see, working with JSON in RxSwift is really easy and now we could subscribe to the connect() method and update our UI by using Driver or Bind if you want more control.