iOS : Let’s Build a Network Abstraction Layer
Swift implementation on top of Alamofire
A network abstraction layer is a must have in any app that interact with a server. In Objective-C, this abstraction layer is usually done in two steps :
- First, subclass the main networking component from our library, usually AFHTTPSessionManager when using AFNetworking.
- Second, create categories on our models — or services of some kind — to put in our networking stuff. All this wrapped in convenient, explicit methods of course.
It’s not too bad, but here comes Swift and we now get a chance to look at this layer from a new angle.
Our goals are:
- Flexibility, to be able to edit or add new endpoints efficiently
- Readability, to have a good idea of how our API work at a glance
- Code safety, with typed parameters. This allow all the pre-compilation goodness we expect from Xcode (completion, validation).
- Easy debugging, meaning being able to insert logs before and after web requests
Let’s imagine we want our app to connect to a web-service allowing us to both fetch and add objects for a given model Color. Our first task is of course to create this model in our app. Once this taken care of, we can start thinking about how we want to interact with this API.
With Swift, enumerations became more powerful than ever. They are a great way to define our endpoints in a readable and type-safe way. Moreover, each enum case can declare associated values of any type to be stored with it.
For each of those Endpoints, we can provide a clear switch-based implementation for the method, path and parameters we’ll want to use.
As you can see, associated values are ideal to wrap every informations needed for our request into one Endpoints enum case.
With a proper representation of our endpoints, we can now create our own request function on top of Alamofire. It will only need an Endpoints enum case and a completion handler to rock and roll!
This function is also the perfect place to put any operations we might want to be executed before and after the request took place. Logging for instance (here I’m using Cocoalumberjack, don’t mind the syntax).
After wrapping all that previous code into a publicly accessible class API, we can call our server like so:
Pretty sweet eh? Readable, type-safe and with only one file to reflect any changes in our API. Mission accomplished!
A project named Moya took the same direction using enums to abstract the network layer. A great library, though I feel Swift makes it actually pretty easy and brief to build it yourself.