Better Routing for IOS Applications with Router in Swift

In this post, I’ll go to talk about other reusable class I’d using in project I was working to make IOS application development more robust. I recently need a Navigation Router to handle different types of URLs in network requests, handle a bunch of .GET, .POST, .PUT. DELETE HTTP request types etc.

Using a separate class for the handling network tasks is great idea. So using a custom Router. It was based on Alamofire of course.

What is Router?

Router is a protocol-oriented approach to handle API / Microservice urls, but itself using as the enum is a better idea. That seamlessly will help the unify and simplify networking routing when making requests by generating URL requests from enum cases.

So, another approach and inspires me some concepts, you can read the blog post in LittleBitesOfCocoa. It is fairliy more lightweight but not meet my requirement.

Creating Router Protocol

First, create a protocol RouterProtocol to make handle four methods to conform REST compatible (get, post, update, destroy) for common API requests will handle (I just declared my own ApiType to get path/route of API URL, so it is not in context, omitted.)

Next thing to do is creating a Router enum is this implementation so why? I’ll explain.

  • First, we need to conform RouterProtocol in order the use our functions.
  • Router enum must be generic type, it have to be accept any kind of structs with RouterProtocol conformance.
  • It receives four verbs (.GET, .POST. PUT, .DELETE etc) so can declare method, path and route properties for them.
  • Creating URLRequest property as NSMutableURLRequest, so add common configurations such as method, defaults headers, OAuth token if available etc.
  • Finally using Alamofire’s Parameter encoding can do required encoding.

Usage

It is fairly simple to use the Router, just declare a method in your ApiManager (I’ll post about my version of ApiManager in another post)

  • In my example, getAccounts method takes AccountsRequest as input and response are AccountsResponse as output, this classes are simply structs, you can roll you own (FYI: In another post I’ll introduce you to Request/Response struct based approach)
  • Your manager (it encapsulated Alamofire instance of course) does the request (Reachability and spinner stuff not in context. I’d post about Reachability you can read in here)
  • Alamofire manager takes Router enum as input and has our RouterProtocol and we said it is a .GET request so I did pass a value like accountsRequest.accountId as String, because in the protocol .GET matches requests have “case get(T, String)”
  • If we need the say it is a .POST request, protocol .POST can have [String: AnyObject]) as a parameter, so in this time I had to pass my accountsRequest input the cast toDictionary() as? [String: AnyObject]) etc.

Simple!

For example; 
Router.get(AccountsRouter(), accountRequest.accountId!).URLRequest

Now you can see creating any kind of Router to any kind of Api is expressive. It is always strictly well defined, understandable and clean.

Code in this post, hosted in Github

Thanks for the reading, I hope you enjoyed.