Chapter 49: Swift Nested If
1. What is a nested if?
A nested if means putting one if statement inside another if statement.
It is used when you need to make a decision only if a previous condition is already true.
Visual structure:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if outerCondition { // this code runs only if outerCondition is true if innerCondition { // this code runs only if BOTH outer and inner are true } else { // outer was true, but inner was false } } else { // outer was false — inner is never checked } |
Nested if answers questions like:
- “If the user is logged in, then check if they have premium”
- “If it’s raining, then check if I have an umbrella”
- “If the form has an email, then check if it’s valid”
2. Very first examples – feel how nesting works
Example 1 – Very simple nesting
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
let isLoggedIn = true let hasPremium = false if isLoggedIn { if hasPremium { print("Welcome back, Premium member! 🎖️") } else { print("Welcome! You have basic access.") } } else { print("Please sign in first.") } |
What happens in different cases:
- isLoggedIn = true, hasPremium = true → “Welcome back, Premium member!”
- isLoggedIn = true, hasPremium = false → “Welcome! You have basic access.”
- isLoggedIn = false → “Please sign in first.” (the inner if is never even looked at)
Example 2 – Temperature + rain check
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
let temperature = 33 let isRaining = true let hasUmbrella = false if temperature > 30 { print("It's hot 🥵") if isRaining { if hasUmbrella { print("But you have an umbrella – good!") } else { print("You should take an umbrella!") } } else { print("No rain – enjoy the sun ☀️") } } else { print("Not too hot today") } |
3. Real-life examples — code you will actually write
Example 1 – User role / permission check (very common)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
let userRole = "admin" let isActive = true let hasSubscription = true if userRole == "admin" { if isActive { if hasSubscription { print("Admin dashboard fully unlocked – all features available") } else { print("Admin account active, but subscription expired – limited access") } } else { print("Admin account is disabled") } } else if userRole == "moderator" { print("Moderator access granted") } else { print("Regular user – basic access only") } |
Example 2 – Form validation (very typical in apps)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
let email = "test@example.com" let password = "Pass123!" let age = 16 let termsAccepted = true if !email.isEmpty { if email.contains("@") && email.contains(".") { if !password.isEmpty { if password.count >= 8 { if age >= 13 { if termsAccepted { print("All checks passed – creating account…") } else { print("You must accept the terms") } } else { print("You must be at least 13 years old") } } else { print("Password must be at least 8 characters") } } else { print("Password is required") } } else { print("Please enter a valid email") } } else { print("Email is required") } |
Notice: This kind of nesting is very common — but also very easy to make messy.
Example 3 – Nested if inside a function (real pattern)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
func canRentCar(age: Int, hasLicense: Bool, hasInsurance: Bool, isWeekend: Bool) -> String { if age >= 21 { if hasLicense { if hasInsurance { if !isWeekend { return "Car rental approved! 🚗" } else { return "Sorry – no rentals on weekends" } } else { return "You need insurance to rent" } } else { return "You need a valid license" } } else { return "You must be at least 21 years old" } } |
4. The Big Problem: Deep Nesting (“Pyramid of Doom”)
When you have many nested ifs, code becomes hard to read:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if a { if b { if c { if d { if e { // happy path } } } } } |
This is called the pyramid of doom — very hard to follow.
5. Better alternatives to deep nesting
Alternative 1 – Use guard (very modern & strongly recommended)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
func canRentCar(age: Int, hasLicense: Bool, hasInsurance: Bool, isWeekend: Bool) -> String { guard age >= 21 else { return "You must be at least 21 years old" } guard hasLicense else { return "You need a valid license" } guard hasInsurance else { return "You need insurance to rent" } guard !isWeekend else { return "Sorry – no rentals on weekends" } return "Car rental approved! 🚗" } |
→ Flatter, easier to read, easier to debug.
Alternative 2 – Combine conditions with &&
|
0 1 2 3 4 5 6 7 8 9 10 |
if age >= 21 && hasLicense && hasInsurance && !isWeekend { return "Car rental approved! 🚗" } else { // figure out which condition failed (more work) } |
→ Shorter, but harder to give specific error messages.
Alternative 3 – Use switch or early returns (later topics)
6. Very Common Beginner Mistakes & Fixes
| Mistake | Wrong code | Correct / Better way | Why? |
|---|---|---|---|
| Forgetting to handle the else case | nested if without final else | Always consider what happens when all fail | Avoids silent failures |
| Deep nesting without guard | 5+ levels of if inside if | Use guard + early return | Much flatter & readable code |
| Not using else if when order matters | multiple separate ifs | Chain with else if when only one should run | Separate ifs can run multiple times |
| Comparing optionals incorrectly | if optional { … } | if let value = optional { … } | optional is Bool? — not what you want |
| Using nested if for simple logic | if a { if b { doX() } } | if a && b { doX() } | Simpler & clearer |
7. Quick Reference – Nested if patterns
| Situation | Typical pattern | When to prefer it |
|---|---|---|
| Simple outer + inner check | if outer { if inner { … } } | Small & clear logic |
| Many required conditions | guard … else { return } (multiple) | Validation / early exit (very modern) |
| One main condition + several sub-cases | if main { if a else if b else if c } | Sub-options only matter if main is true |
| Optional unwrapping + check | if let value = optional, value > 10 { … } | Safe & concise |
| Deep permission / state check | guard chain | Flattest & easiest to read |
8. Small Practice – Try these
- Write nested if for weather advice:
- If temperature > 30 → “Hot”
- If raining → “Take umbrella”
- Else → “Wear sunglasses”
- Else → “Normal weather”
- If temperature > 30 → “Hot”
- Write code that checks:
- If logged in
- If premium → “Premium content”
- Else → “Basic content”
- Else → “Sign in required”
- If logged in
- Write a function that returns a message based on:
- If age >= 18
- If hasLicense → “Can drive”
- Else → “Adult but no license”
- Else → “Under 18”
- If age >= 18
Paste your code here if you want feedback or want to see cleaner/more modern versions!
What would you like to explore next?
- guard statement in depth (very important companion to nested if)
- switch statement (often cleaner than deep if…else if)
- if let / optional binding with if
- Conditional logic in SwiftUI (conditional views)
- Or move to another topic (loops, functions, arrays, optionals…)
Just tell me — we’ll continue in the same clear, patient, detailed style 😊
