Cinamofryer – iOS Networking Manager SDK
Implementing a quality network layer of an app can be quite challenging. That's where networking libraries come in, and they aim to make this task vastly less tedious.
Networking is an essential component of mobile app development. It’s the crucial piece of logic that communicates with your API and handles all HTTP requests and responses that put your app into operation. Today, it’s hard to find a modern app that doesn’t perform any network requests to communicate with an API of some sort. That’s why it’s important to know how to efficiently handle this network-specific code. Fortunately, there are various solutions available that aim to offload this implementation for you, while fitting into your app’s architecture. Some developers find using networking libraries to be the simplest solution, whereas others think it's not necessary to include an extra dependency, and prefer the flexibility of implementing this part themselves. Needless to say, there’s no right way or universal solution that works for each project and each developer. In this article, we will dive into the details of something we found that works best for us.
Our Networking Manager SDK
In our previous blog of this series, we presented you with the basics of our iOS project template – how it came into being, its architecture, and how you can use it to kick-start your own projects.
As anticipated, we continued working on our template, upgrading it and trying to make it as useful to us as possible. We implemented and separated the networking layer into a standalone manager, Cinamofryer – our own iOS networking library.
Cinamofryer is an extremely lightweight HTTP networking library that allows you to perform simple and clean network calls. It's written in Swift and wrapped around the async/await pattern. It brings together the URLSession, async-await pattern, Decodable and Generics to simplify sending API requests.
So, why did we implement our own networking library with so many powerful ones already out there in the iOS community?
We set our hearts on an extremely lightweight and clean networking manager that we would be able to adjust precisely to fit our needs. We wanted to isolate our recurrent networking logic, making it more reusable, but not dependent on third party libraries like Alamofire.
Besides, we preferred having a simple networking library that wouldn’t have numerous functionalities, most of which we would likely never use. One that we could customize and upgrade, and over which we would have total control of its functionality and mechanics – while also learning a couple of new things working on it.
We wanted to be able to use it in any of our projects, yet to be small enough that it would barely require any documentation before using it.
And on top of all that, we wanted a networking manager that would suit our iOS project template nicely.
Details and Usage
Now that we got our reasoning out of the way, let’s present some of Cinamofryer’s key parts that make implementing our network communication pain-free.
So, let's have a look at what its responsibilities are, how it’s implemented, and finally how you can use it in your own projects.
The key requirements we set for this library were:
minimal asynchronous requests adapted for the async/await syntax
clean response serialization
simple yet sufficient error handling
support for file upload requests
First of all, like any other networking library out there, it allows you to perform some essential API requests. There are, in fact, two types of requests you can send using our network manager – basic API requests and file upload requests.
Making a basic request is as simple as calling the request method, which finally returns an object of a generic type T.
All you need to do is pass your URL and a desired HTTP method – GET, POST, DELETE, PUT or PATCH. You can also pass parameters, which are by default JSON-encoded and sent in the request body, and headers.
The contentType can be .JSON or .formUrlEncoded.
Let’s dive a bit more into detail of how this method works.
The foundation for decoding the received API responses are the Generics and the Codable protocol.
The JSON object from the response is decoded to an object of a generic type T, where T is Codable.
The way it works is that it will inform the networking manager about what kind of data we are expecting, and what kind of object we need it to return.
So, all we need to do is to define our Codable model, and let our network manager deserialize the response for us.
The neat thing about this approach is that it’s type-safe!
Before sending a request that contains parameters, we first need to define how we want them encoded.
The default encoding is .JSON. For mapping a Codable model to a dictionary, you can use the asDictionary method.
Queries are also supported, so if you need to use URL encoded form data, set contentType to .formUrlEncoded. The parameters will be encoded and URL safe.
Sending a Basic Request
Now that we covered some fundamentals of our basic request method, let’s have a look at a simple example of using it to send a POST request.
This example illustrates a function for sending a POST request for adding new users.
As parameters, we pass a Codeable model of type User, mapped to a dictionary using the asDictionary method. Since no contentType is defined, the default JSON encoding will be used. And finally, we pass an authorization header to the headers property.
Sending an Upload Request
Being able to upload a file to a server is a rather essential feature of a networking manager. For that reason we defined the uploadRequest method.
If successful, like the basic request method, it ultimately returns a generic object of type T.
Let’s take a look at its definition.
It accepts the following parameters:
url – the URL of your endpoint.
method – a desired HTTP method, which in this case can only be POST or PUT.
data – an object of type UploadData, which defines the name, data and the file type of your file.
requestType – either .multipartFormData or .binary.
headers – the request headers.
progressHandler – for tracking the upload progress.
Tracking the Upload Progress
File uploads can be lengthy activities, and sometimes we need to show the user the progress of their upload to give a better user experience.
In those cases, you can implement and pass the progressUpload handler to the uploadRequest method.
If there’s one thing that every developer is familiar with, it’s that nothing ever works as expected. By handling API errors you are making your application more robust as well as providing a better user experience.
As we already mentioned, if the request is successful, we'll get an object of a generic type T that we defined. On the other hand, if something goes wrong and the API returns an invalid status code, fails to encode or decode data, and so on – an error will be thrown.
There are currently three custom errors that our networking manager can throw.
If the response status code is not between 200 and 299, i.e. not a Success, it will throw an invalidStatusCode, along with the exact status code that was returned.
If you pass a string that cannot be converted to a URL data model, an invalidURL error will be thrown.
And finally, invalidHTTPMethod is thrown If the passed HTTPMethod is not allowed – e.g. a GET method for an image upload request.
If the error is, however, caused by JSONDecoder, JSONEncoder or JSONSerialization, it will be forwarded with the original message, so you can catch it and log it to the console to see the exact source of the problem – and handle it in an appropriate manner.
Cinamofryer is available as a public repository on our GitHub and you can start using it straight away. The installation is pretty straightforward and can be done in seconds.
The package can easily be added to your desired iOS project via the Swift Package Manager using the repository link:
Once you’ve added the package, all you’ll need to do is to simply import Cinamofryer wherever you’d like to use it.
And that’s pretty much it! You can now try out the functionalities our network manager provides and start sending your API requests with ease.
As you can see, it doesn't take much to get started with our iOS networking library. It’s very lightweight and straightforward, and provides the essential features for effective network communication.
Keep in mind that this is only its first version, and we will keep upgrading it and adding features that show useful to us.
Also, don’t forget to take a look at our iOS project template source code if you wish to see our networking manager in action!
Subscribe to our newsletter
We send bi-weekly blogs on design, technology and business topics.