Alamofire Tutorial: Getting Started

Take your first steps into Alamofire, the de facto networking library on iOS powering thousands of apps, by using the Imagga APIs to upload and analyze user photos. By Ron Kliffer.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Improving PhotoTagger

You probably noticed some repeated code in PhotoTagger. If Imagga released v2 of their API and deprecated v1, PhotoTagger would no longer function and you'd have to update the URL in each of the three methods. Similarly, if your authorization token changed you'd be updating it all over the place.

Alamofire provides a simple method to eliminate this code duplication and provide centralized configuration. The technique involves creating a struct conforming to URLRequestConvertible and updating your upload and request calls.

Create a new Swift file by clicking File\New\File... and selecting Swift file under iOS. Click Next, name the file ImaggaRouter.swift, select the Group PhotoTagger with the yellow folder icon and click Create.

Add the following to your new file:

import Alamofire

public enum ImaggaRouter: URLRequestConvertible {
  // 1
  enum Constants {
    static let baseURLPath = "http://api.imagga.com/v1"
    static let authenticationToken = "Basic xxx"
  }
  
  // 2
  case content
  case tags(String)
  case colors(String)
  
  // 3
  var method: HTTPMethod {
    switch self {
    case .content:
      return .post
    case .tags, .colors:
      return .get
    }
  }
  
  // 4
  var path: String {
    switch self {
    case .content:
      return "/content"
    case .tags:
      return "/tagging"
    case .colors:
      return "/colors"
    }
  }
  
  // 5
  var parameters: [String: Any] {
    switch self {
    case .tags(let contentID):
      return ["content": contentID]
    case .colors(let contentID):
      return ["content": contentID, "extract_object_colors": 0]
    default:
      return [:]
    }
  }
  
  // 6
  public func asURLRequest() throws -> URLRequest {
    let url = try Constants.baseURLPath.asURL()
    
    var request = URLRequest(url: url.appendingPathComponent(path))
    request.httpMethod = method.rawValue
    request.setValue(Constants.authenticationToken, forHTTPHeaderField: "Authorization")
    request.timeoutInterval = TimeInterval(10 * 1000)
    
    return try URLEncoding.default.encode(request, with: parameters)
  }
}

Here's a step-by-step explanation of the above code:

  1. Declare constants to hold the Imagga base URL and your Basic xxx with your actual authorization header.
  2. Declare the enum cases. Each case corresponds to an api endpoint.
  3. Return the HTTP method for each api endpoint.
  4. Return the path for each api endpoint.
  5. Return the parameters for each api endpoint.
  6. Use all of the above components to create a URLRequest for the requested endpoint.

Now all your boilerplate code is in single place, should you ever need to update it.

Go back to ViewController.swift and in upload(image:progress:completion:) replace:

Alamofire.upload(
  multipartFormData: { multipartFormData in
    multipartFormData.append(imageData,
                             withName: "imagefile",
                             fileName: "image.jpg",
                             mimeType: "image/jpeg")
  },
  to: "http://api.imagga.com/v1/content",
  headers: ["Authorization": "Basic xxx"],

with the following:

Alamofire.upload(multipartFormData: { multipartFormData in
  multipartFormData.append(imageData,
                           withName: "imagefile",
                           fileName: "image.jpg",
                           mimeType: "image/jpeg")
},
  with: ImaggaRouter.content,

Next replace the call for Alamofire.request in downloadTags(contentID:completion:) with:

Alamofire.request(ImaggaRouter.tags(contentID))

Finally, update the call to Alamofire.request in downloadColors(contentID:completion:) with:

Alamofire.request(ImaggaRouter.colors(contentID))
Note: Be sure to leave the responseJSON handlers in place for both of the previous edits.

Build and run for the final time; everything should function just as before, which means you've refactored everything without breaking your app. However, you don't have to go through your entire source code if anything on the Imagga integration ever changes: APIs, your authorization token, parameters, etc. Awesome job!

Where To Go From Here?

You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial. Don't forget to replace your authorization token as appropriate!

This tutorial covered the very basics. You can take a deeper dive by looking at the documentation on the Alamofire site at https://github.com/Alamofire/Alamofire.

Also, you can take some time to learn more about Apple's URLSession which Alamofire uses under the hood:

Please share any comments or questions about this tutorial in the forum discussion below!