Generic networking layer using Combine in Swift UI.

James Rochabrun
If let swift = Programming!
4 min readJul 23, 2020

--

In this short post, I will show you how to create a generic Networking API that you can reuse in your own implementations using generics and Combine. We won’t go in-depth of explaining elements of the Combine framework, instead, I will show you an example on how to use generics to boost your code reusability.

You will see here:

  1. Mix of generics and Combine Framework to create a reusable networking layer.
  2. Display elements from a network response in a SwiftUI list.

Don’t want to keep reading give me the code!. 😡

Let’s divide this into 3 simple steps…

Step 1: Build the generic networking layer.

Imagine you have to build an API that handles a request, handles errors, decodes the response, and also retries the network call if it fails 😳.

Well using Combine it will look as simple as this…

🤯

What do we have…

1 .- A protocol that has an URLSession and a function that returns a Publisher .

2 .- Extending the protocol so we can have a default implementation.

3 .- Here is how we improve our networking layer, if you don’t see it already I highly recommend checking this talk to see what is new in networking for iOS. We will use the dataTaskPublisher from the Combine framework instead of using a simple dataTask.

That’s it, now you have a generic API that can Decode any kind of object! 🙃

As you can see the code is more readable and concise, now let me show you how to use it in your own client…

Step 2: Adopting the Protocol in your own client.

What do we have…

1 .- The URLSession to satisfy the CombineApi protocol.

2 .- A couple of convenient initializers to facilitate instantiation.

3.- MovieFeed is a model that contains everything we need to perform a URLRequest , the code of it is irrelevant for this post because you can model it as you wish, but here is an idea.

4.- Here we call the execute method passing as parameters a request, the meta-type of the object that we want to decode, and an integer to define the number of retries in case it fails.

With all of this, you can create a model that conforms to the ObservableObject protocol to wrap your client networking logic, like this…

Step 3: Defining an ObservableObject.

1 .- A class that conforms to ObservableObject , it will be able to notify updates before the object has changed.

2 .- An AnyCancellable Subscriber to cancel the subscription on deallocation.

3 .- A Publisher that streams the changes in the collection.

4 .- An instance of your client. 😉

5.- Combine uses the .sink closure that attaches a subscriber with closures that gets executed on completion and when there is a new value available, by assigning the value to the movies publisher, it will publish the changes 🚀.

The cool thing here is that you can also reuse this code in an UIKit application but just for fun let’s see how it will do it using SwiftUI…

  1. - Since iOS 14 you can build apps using just Swift UI, the @main keyword and the App protocol defines the starting point of your app.
  2. Since iOS 14 you can use @StateObject as well as @ObservedObject , both works in the same way but the first one has improvements in performance, the MoviesProvider is the @ObservableObject we just created.
  3. Since iOS 14 you also need to have a struct that conforms to the @Scene protocol to “wrap” your application.
  4. A navigation view, if you want to perform any navigation tasks.
  5. Big shout out to generics, if you didn’t notice already, they are everywhere! As you can see the List view is a container that takes an array of any kind of elements, a keypath (This id comes from the Identifiable protocol and every movie view model has one check it here.).
  6. List has a closure that provides an element from the array and it returns any kind of view that conforms to View protocol, if you are thinking in UIKit this is the equivalent of a cell. (repo for the movie row implementation here.)

Here is the app! in the next post I will show you how to load images in the items of your list using combine and how to create a custom Image view to cache them.

Here is the full repo. 🤖

--

--