The more I work with enums in Swift, the more I find uses for them in my every day coding. Recently I worked on a project that used Alamofire to connect to a JSON API.

Modeling each endpoint as an enum allowed me to encapsulate all of the information needed to connect to the endpoint in one place.

I began by making an AlamofireEndPoint protocol and protocol extension. This provides all the information Alamofire needs to connect to a JSON endpoint.

Next, I create a Result type that allows me to return either Success or Failure from the networking call. This approach prevents you from getting into funky situations where a method returns both successfully but with an error. Its not required for this approach, but its a best practice and another example of how enums can be useful.

Now we can make an AlamoFireJSONClient with a single method that can be used to connect to every endpoint in your app. It takes as parameters an AlamofireEndPoint and a (Result<Any>)->() completionHandler.

The completionHandler returns Any because at this point we don’t know if the JSON will be [String : Any] or [Any]. It will be the responsibility of the caller to have that knowledge and downcast it appropriately.

We now have everything we need to connect to any JSON API (that doesn’t require sophisticated auth, but this approach could be extended). To demonstrate, I’ll use this StarWars API and model the /planets endpoint.

I’ll start be creating a StarWarsJSONClient protocol and protocol extension that will allow me to handle the result of the AlamofireJSONClient’s makeAPICall(to: completionHandler:).

All responses from the StarWars API have the same JSON format of [String : Any] so we can encapsulate that information here.

The first endpoint we’ll model is /planets. This contains information on every planet ever mentioned in StarWars. For each case, we add associated values required to make the API call. For example to get information about a specific planet we pass in an ID.

We encapsulate the knowledge of how to create the parameters needed for this endpoint here in private methods.

Finally, we make a PlanetsJSONClient that conforms to the StarsWarsJSONClient protocol. In a real app, I’d have a PlanetsFetcher that would then call this PlanetsJSONClient and transform the JSON into model objects to be used in the app.

You can download the demo project on Github. I’d love to hear your thoughts on this approach.