Making constants with an enum
Here's a really good use for enum: We can use enum to create a restricted subset of some type, much as we did with the preceding Coordinate enum.
For example, when we are defining HTTP request code, we don't want any typing mistakes to find their way into our String objects, rendering the keys (silently) unusable.
A common solution is to create a list of constant strings like so:
let kUserName = "userName"
let kPassword = "password"
let kvideoPath = "/video"
And so on.
But these keys can still get mixed up, since they are simply String objects, and so the compiler cannot check that we are passing the right strings. Any String will keep the compiler happy.
By using an enum, we can gather together any number of String objects under one type:
enum APIKey: String
{
case userName, password, email
}
Now when we need to specify method parameter types, and any other type-related definitions, we can use the APIKey type instead of the String type, thereby ensuring that the string "/video" can never be passed as an API key--the compiler will complain (and refuse to compile, of course).
In our data layer, far away on the other side of the program, we may declare something like the following:
typealias APIParams = [APIKey: String]
And now we can't mess up assigning one of the valid strings to anything declared to be of type APIKey:
let userCredentials: APIParams = [.userName: "Ali Baba",
.password: "Open Sesame",
.email: "notinvented@themoment"]
Back in the HTTP service layer, we can then safely extract the String values from the APIKey typed values:
var httpParameters: [String: String] = [:]
for apiKey in userCredentials.keys
{
httpParameters[apiKey.rawValue] = userCredentials[apiKey]
}
This leads to significantly safer code when passing strings around, strings that would otherwise happily compile and lead to complete confusion when the HTTP request comes back with the following error message:
"What??"