Enums with associated values can be very useful in Swift, but once you add associated values you lose some properties, especially equality:
enum AuthenticationResponse {
case success
case alert(Alert)
case reauthenticate
}
Testing for a specific case requires a switch statement or the if pattern match syntax:
if case .success = response { … }
But while this works well for control flow, it doesn’t work well for cases where we want a Bool, such as assert(). There are also common situations with lists and libraries like RxSwift where a filtering function uses a Bool valued closure. In these situations the best we can do is write functions like:
enum AuthenticationResponse {
case success
case alert(Alert)
case reauthenticate
var isSuccess: Bool {
if case .success = self {
return true
} else {
return false
}
}
var isReauthenticate: Bool {
if case .reauthenticate = self {
return true
} else {
return false
}
}
var isAlert: Bool {
if case .alert(_) = self {
return true
} else {
return false
}
}
}
Any suggestions better than writing out each of these functions explicitly?
The conditional conformances proposal coming in Swift 4 solves some of this issue, but not completely. If Alert isn’t Equatable, it is still useful to test whether the result is .success. For example:
assert(response == .success)
This is perfectly intelligible and I would argue that equality should be defined for enums with associated values omitted:
assert(response == .alert)
Here we are ignoring the associated values, and merely checking if the enum case is the same.
Andy