Swift’s if case syntax is a clean, powerful way to match enum cases — especially when you’re only interested in one specific case. Instead of using a full switch statement, the if case lets you pattern-match directly inside an if condition, making your code more concise and focused.
What Is if case in Swift?
The if case syntax performs pattern matching against a single enum case, without requiring you to handle every possible case. It’s essentially a shortcut for when a full switch would be overdone.
Here’s a simple example using switch:
enum TrafficLight {
case red, yellow, green
}
let current = TrafficLight.red
switch current {
case .red:
print("Stop!")
default:
break
}
This works perfectly fine — but if you only care about one specific case, if case makes the same logic more concise:
if current == .red {
print("Stop!")
}
The real capability of if case shows up when you’re dealing with associated values — something == can’t handle directly.
Matching Enum Cases with Associated Values
Let’s say you’re working with an enum that has associated values:
enum FileStatus {
case uploading(Int)
case success(String)
case failed(Error)
}
Using if case let, you can both match a specific case and bind its value:
let status = FileStatus.success("Upload complete")
if case let .success(message) = status {
print("Message: \(message)")
}
Why if case let Is Often Preferred?
When you’re working with enums that have associated values, both if case and if case let allow you to pattern-match and optionally extract those values. But if case let is often the more convenient choice — especially when readability and clarity matter.
Let’s look at this example using a simple enum:
enum DownloadState {
case inProgress(Int)
case completed(String)
}
let state = DownloadState.completed("File.zip")
Using if case:
if case .completed(let fileName) = state {
print("Completed download: \(fileName)")
}
Using if case let:
if case let .completed(fileName) = state {
print("Completed download: \(fileName)")
}
So, what’s the difference?
- if case + let: You’re explicitly matching the pattern and binding the associated value inside the pattern itself.
- if case let: You push the let to the front, which reads more naturally, especially when extracting multiple values.
Both are functionally identical — they both match a single case and bind associated values. But if case let becomes easier to read when you’re dealing with more complex enums.
Use Case 1: Pattern Matching with Optionals
One powerful feature of the if case is its ability to match enums inside optionals — commonly used with Swift’s Result or custom optional enums.
let outcome: Result<String, Error>? = .success("Done")
if case .success(let message)? = outcome {
print("Outcome: \(message)")
}
Use Case 2: Pattern Matching with Multiple Values
In advanced use cases, if case can even match multiple values using tuples. This works great for comparing multiple enums at once:
let first = FileStatus.success("First")
let second = FileStatus.success("Second")
if case (.success(let firstMsg), .success(let secondMsg)) = (first, second) {
print("Both succeeded: \(firstMsg), \(secondMsg)")
}