The best way to consume and manage APIs in iOS applications

Keep APIs in your application manageable and structured

Shubham Singh
Mac O’Clock
6 min readApr 18, 2020

--

A Mac book with some code on it accompanied by a bulb

Consuming APIs in your iOS application can be intimidating and though there are numerous ways to achieve the same, maintaining them can be a bit tricky and overwhelming.

I have struggled to efficiently manage the code where the APIs were defined, as it kept getting longer every time for each new request.

In this article, I’m going to share with you the best way I have found to comfortably maintain all the API calls with Alamofire.

This tutorial assumes you know of:

  • Swift 5
  • Xcode
  • CocoaPods

Let’s get started now

Preparation

We are going to use Alamofire for this tutorial, if you know how to install and use pods in your application you can skip this section.

For those of you who aren’t familiar with Cocoapods follow along :)

1. Initialize the Podfile

Go to the project directory in the terminal and run the following command.

2. Add the Alamofire dependency

Open the Podfile and add the code for installing Alamofire.

3. Install Alamofire

Now go back to the terminal and run this command to install the pod’s

Now you can start Xcode by opening the .xcworkspace file.

Creating the Manager for APIs

We are going to create a new Swift file called APIManager.swift that will contain the manager for the API calls.

For the scope of this article, we are going to call simple APIs which returns the result of this format

I will be demonstrating 3 API calls in this article —

  • GET call to fetch a single entry
  • GET call to fetch multiple entries
  • POST call to send an entry to the server

1. Create the Model for the API response

Before we start consuming API’s we have to create a Model for the same.

Since Swift 4 creating Models for APIs has become a piece of cake thanks to the Decodable and Encodable protocol.

We will be creating a struct called Resource which conforms to the Decodable protocol. It should look something like this —

Once we have created the model, we can start working on the APIManager.

2. Create the APIManager

Now we will create an enum APIManager which will conform to the URLRequestConvertible protocol defined in the Alamofire Library.

URLRequestConvertible allows us to break down the URLRequests and modify every aspect of the Request such as the HTTPMethod, Parameters, Path, Encoding and Headers.

The reason why we need to create this APIManager as an enum is to formulate cases for various API requests.

We have defined the endpoint for the API and along with it 3 cases for the API calls, if the request has any parameters to be passed, it should be declared in the case.

i) Customize the cases for the requests

Here we have specified the paths for each of the API requests, pretty much self-explanatory.

ii) Add the variables to specify the HTTP method and encoding for requests.

The HTTP method for the requests is specified inside another variable called method. I am using the default encoding for my requests if your API requires another type of encoding you can specify it.

iii) Extend the function provided by the URLRequestConvertible which returns the URLRequest for each case.

The requests are generated using the path, encoding, and method specified above for each case. For POST calls you can pass the parameters as I have for the createResource case. The headers are also added here if needed.

iv) Create the functions for consuming the APIs

We finish our APIManager enum by adding the calling functions to call the URLRequestConvertible cases.

We pass the URLRequestConvertible case which we created to the Alamofire method —

The response method is called to get the response of the request. Here we have used the responseJSON method to get the API response.

At last, we convert the API response with the help of JSONDecoder and cast it to our Decodable struct Resource.

Since the second API returns multiple resources we cast it into an array of Resources.

With the data cast to our specified model, we return it with the completionHandler.

This completes our APIManager.

That was long, can we call the APIs now?🤔

Yes, that’s correct. We have everything that we need, the functions defined in the APIManager is used to call APIs.

We can call the APIs now in our viewControllers and use them accordingly.

But is it worth structuring our APIs this way?

You might be thinking that this way of structuring the APIs was unnecessary and you would be better off calling the APIs directly with Alamofire.

Trust me that once the number of the APIs consumed in your app increases, it will help you to keep things structured and tidy since all the APIs are defined in one place. You can even modify the cases according to your own needs based on your requirements.

It also has other benefits —

You can also generalize the calling functions within a single Template so that you can form a sole function for similar APIs -

The function created above takes a URLRequestConvertible and a Model. For APIs returning the data in a similar manner, the same generic function can be used.

We can call the generic function by passing our defined URLRequestConvertible and the model Resource to call the GET API returning a Single entry.

Now, this dramatically reduces the lines of code we need to write for the calling functions in our APIManager and saves a lot of our time!

Conclusion

If you embrace this way of structuring your APIs for your iOS applications, your code management will definitely improve and you will save a lot of your time.

If you want the code, it’s available in my Github repository SimpleAFire.

We now come to the end of this article, I hope it was helpful, and you learned something!

Thanks for reading!

--

--

Shubham Singh
Mac O’Clock

iOS developer at Dailyrounds. I’m Immensely passionate about iOS & I’m also an avid UI/UX enthusiast. Connect with me on my Instagram/Twitter — @shubham_iosdev