Fabian Buentello

Using Enum Dictionaries as Arguments

3 minute read

Intro and Problem

I learned a lot of things while developing Cely, but by far one of the coolest things I learned was using a enum dictionary as a way to pass in arguments. This would act as a replacement to having optional parameters with default values. To illustrate what I’m talking about, check out this example:

enumRequestOptions{casehttpMethodcaseencodingcasebody...}// not including completion block for examplefuncrequest(_apiEndpoint:String,options:[RequestOptions:Any?]){lethttpMethod=options[.httpMethod]as?HTTPMethod??.getletbody=options[.body]as?[String:Any?]??[:]...}...// usagerequest("/example",options:[.httpMethod:.post,.encoding:JSONEncoding.default,.body:["username":"initFabian"]])...

I came across this problem while writing Cely’s setup(_:) method. This method gets called inside of AppDelegate.swift and needs to be short and simple. Here are the optional parameters for setup(_:) that would’ve made my method extremely lengthy had they not be placed in an enum dictionary:

Ability to use a customized login screen(via storyboard).

Ability to use a storyboard other than Main.storyboard as an entry point to the application.

If using Cely’s default login screen, allow completion block once the login button is pressed.

If using Cely’s default login screen, allow the user to style the login screen.

Allow the use of a different storage to store credentials, i.e.: plists or documents.

Current Solution

That’s a pretty heavy list huh? If we were to strictly follow swift practices, we would see a method declaration as such:

I decided to explore alternative, more creative ways to solve my problem. I wanted to give users options when using Cely, but most importantly, I wanted to be able to add new options easily without breaking/renaming methods. So I thought about how we do this in JavaScript, more specifically, a URL request in JavaScript. If you look at most popular JavaScript Networking Libraries, you’ll see the majority of them set options inside of a dictionary:

My Solution

I definitely wanted the user to add options using a dictionary, but I didn’t want the user to be using strings as keys. That’s when the thought of enums came to mind since it would throw errors if typos were made. This allowed the user to set the options they needed without bloating the declaration for setup(_:). So I created an enum called CelyOptions with the following cases:

Expand the options table for CelyOptions inside of Cely’s documentation for more examples

Conclusion

I understand this approach is not for every use case, but when used appropriately, it can be quite powerful. As I’m reviewing old code, I’m seeing where this pattern would be useful. I feel things such as Network calls, components(like custom segmented controllers), and especially generic UITableView datasource/delegate classes(will be a post for the future) would highly benefit from this pattern. If you ever find yourself using this pattern, or if this pattern sparks an idea, please reach out!