Chapter 56: Real-Life Examples
1. Retry a failing operation (most classic real-life use of while)
Network calls, file operations, payment gateways, Bluetooth connections, etc. — they fail sometimes. A very common pattern is: try again a few times before giving up.
|
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 |
func tryToConnectToServer(maxRetries: Int = 4, delaySeconds: Double = 2.0) -> String? { var attempt = 0 while attempt < maxRetries { attempt += 1 print("Attempt \(attempt) of \(maxRetries) – connecting to server...") // Simulate network call (random success/failure) let success = Bool.random() // in real code: URLSession, API call, etc. if success { print("Success!") return "Connected – welcome!" } print("Failed. Waiting \(delaySeconds) seconds before retry...") Thread.sleep(forTimeInterval: delaySeconds) } print("All \(maxRetries) attempts failed.") return nil } // Usage if let result = tryToConnectToServer() { print(result) } else { print("Could not connect – please check your internet and try again later.") } |
Why while here?
- We don’t know in advance how many attempts we’ll need (could succeed on 1st, or fail all)
- We have a clear exit condition (attempts reach limit)
- We want to control the delay and logging between attempts
Safety improvement (very common in production code):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
while attempt < maxRetries { attempt += 1 // ... if success { return result } // exponential backoff (realistic) let waitTime = delaySeconds * pow(2.0, Double(attempt - 1)) print("Waiting \(waitTime)s...") Thread.sleep(forTimeInterval: waitTime) } |
2. Keep asking user for valid input (command-line tools, setup wizards)
|
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 36 37 38 39 |
func getValidUsername() -> String { var username = "" while true { print("Choose a username (3–20 characters, letters/numbers/underscores only):") if let input = readLine()?.trimmingCharacters(in: .whitespacesAndNewlines) { username = input if username.count < 3 || username.count > 20 { print("Username must be between 3 and 20 characters.") continue } let allowed = username.allSatisfy { char in char.isLetter || char.isNumber || char == "_" } if !allowed { print("Only letters, numbers, and underscores allowed.") continue } // all checks passed break } else { print("Please enter something.") } } return username } let chosenName = getValidUsername() print("Great! Your username is: \(chosenName)") |
Why while true + break here?
- We must keep asking until valid input → no “maximum tries”
- while true + break is very readable for “keep going until I say stop”
- continue skips to next iteration when input is bad
3. Accumulate / collect until goal is reached
|
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 |
let savingsGoal: Double = 100_000 var currentSavings: Double = 0 var month = 0 while currentSavings < savingsGoal { month += 1 let monthlyIncome = 48_000.0 let monthlyExpenses = 35_000.0 + Double.random(in: -8_000...8_000) // simulate variation let savingsThisMonth = monthlyIncome - monthlyExpenses currentSavings += savingsThisMonth print("Month \(month): saved ₹\(String(format: "%.0f", savingsThisMonth)) → total: ₹\(String(format: "%.0f", currentSavings))") // safety: prevent infinite loop if expenses always > income if month > 120 { print("Warning: 10 years passed – goal not reached. Check your budget.") break } } if currentSavings >= savingsGoal { print("Goal reached after \(month) months! 🎉") } else { print("Could not reach goal in reasonable time.") } |
Why while here?
- We don’t know how many months it will take
- We have a clear stopping condition (savings ≥ goal)
- We added a safety counter (max 120 months) — very good habit
4. Process items until list is empty
|
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 |
var tasks = [ "Buy groceries", "Finish report", "Call mom", "Reply to emails", "Gym" ] print("Processing tasks one by one...\n") while !tasks.isEmpty { let nextTask = tasks.removeFirst() print("Doing: \(nextTask)") // simulate work print(" → completed!") print(" Remaining tasks: \(tasks.count)\n") } print("All tasks finished! 🎯") |
Alternative (often cleaner – many developers prefer this):
|
0 1 2 3 4 5 6 7 8 9 |
while let nextTask = tasks.first { tasks.removeFirst() print("Doing: \(nextTask)") } |
5. Very Common Beginner Mistakes & How to Fix Them
| Mistake | Wrong / Dangerous code | Correct / Better habit | Why? |
|---|---|---|---|
| Forgetting to update the condition variable | while count > 0 { print(count) } | count -= 1 inside loop | Infinite loop |
| Using while true without safe exit | while true { … } | while true { if done { break } } or counter | Hard to see when it stops |
| Not handling empty collection | while array.count > 0 { array[0]… } | while let item = array.first { array.removeFirst() } | Prevents crash / infinite loop |
| Modifying collection while looping over it | for item in array { array.append(item) } | Use while + removeFirst() or indices | Runtime error: collection mutated |
| No safety limit | while !success { tryAgain() } | var attempt = 0; while … && attempt < 10 { … } | Prevents infinite loop in case of bug |
6. Quick Summary – When to reach for while
| Situation | Use while or repeat … while? | Alternative (when to prefer) | Typical pattern |
|---|---|---|---|
| Retry until success (network, payment, input) | Yes | for try? in some async cases | while attempt < max { try… } |
| Keep asking user until valid input | Yes (repeat … while) | while + optional binding | repeat { readLine() } while invalid |
| Accumulate until goal / threshold | Yes | for if fixed steps | while savings < goal { savings += monthly } |
| Process collection until empty | Yes | for item in array { … } if not modifying | while !array.isEmpty { array.removeFirst() } |
| You know exact number of iterations | — | for i in 0..<count { … } | for is clearer & safer |
7. Small Practice – Try these now
- Countdown Start from 10, count down to 1 with while, then print “Lift off! 🚀”
- Savings until goal Goal: ₹50,000 Start with ₹0 Each month add ₹4,500 + random bonus (–₹500 to +₹1,500) Print month and current savings until goal is reached
- PIN entry Use repeat … while to keep asking for a 4-digit PIN until user enters exactly 4 digits (0-9)
Paste your code here if you want feedback, corrections, or more elegant versions!
What would you like to explore next?
- repeat … while in more depth
- while let pattern (very common with optionals)
- Infinite loops — how to debug & prevent them safely
- while vs for vs forEach — decision guide
- Loops in SwiftUI (ForEach vs manual while)
- Or move to another topic (switch, functions, arrays, optionals…)
Just tell me — we’ll continue in the same clear, patient, detailed style 😊
