Alamofire 3.0 will be released soon so now is a good time to start looking at how best to build an API client for our app. We'll be covering different areas of this topic periodically over the next few weeks.

Today we'll start by looking at one part of the equation: routing.

We've talked about routing before in the context of iOS URL schemes and libraries like JLRoutes (Bite #62). This is a bit different. We'll be creating a Router type that will help us unify and simplify our code when we make requests by generating URL requests from enum cases.

enum Router: URLRequestConvertible {
  static let baseURL = NSURL(string: "https://littlebitesofcocoa.com")!

  case Bites
  case Bite(Int)
  case BitesTagged(Int)

  var URL: NSURL { return Router.baseURL.URLByAppendingPathComponent(route.path) }

  var route: (path: String, parameters: [String : AnyObject]?) {
    switch self {
      case .Bites: return ("/", nil)
      case .Bite (let biteID): return ("/\(biteID)", nil)
      case .BitesTagged(let tagID): return ("/", ["t": tagID])
    }
  }

  var URLRequest: NSMutableURLRequest {
    return Alamofire
      .ParameterEncoding
      .URL
      .encode(NSURLRequest(URL: URL), parameters: (route.parameters ?? [ : ])).0
  }
}

We'll start by declaring a new enum type that conforms to the URLRequestConvertable protocol (which comes from Alamofire). Then we'll define a few different cases that each correspond to an endpoint on our HTTP API. We'll add a computed route property that returns a tuple to translate from our enum cases into URL path and parameter values.

Finally, we'll finish conforming to URLRequestCovertable by adding a computed property that encodes our URL and parameters into an NSMutableURLRequest. Neat.

Now we can use our new Router to write some super clean Alamofire request code like this:

Alamofire.request(Router.Bites)
  .responseObjects { (response: Response<[Bite], NSError>) in
    let bites = response.result.value
    print(bites)
  }

The responseObjects custom response serializer converts JSON to our own custom struct types. We'll look at how to create it in the near future.

We can also access raw URL requests like this:

let request = Router.Bite(93).URLRequest