VOOZH about

URL: https://dev.to/gamya_m/swift-while-loops-keep-going-until-the-job-is-done-3hl5

⇱ Swift Loops — while, repeat and Knowing When to Use Each 🔄 - DEV Community


In our last article we covered for loops — perfect for when you know exactly how many times you need to repeat something. But what happens when you don't know how many times you'll need to loop?

That's where while and repeat loops come in. 🧠


🔄 The While Loop — Run Until a Condition Is False

A while loop keeps running as long as a condition is true. The moment the condition becomes false, the loop stops:

while someCondition {
 // code to repeat
}

No array needed. No range needed. Just a condition. Let's see it in action:

var countdown = 10

while countdown > 0 {
 print("\(countdown)...")
 countdown -= 1
}

print("Blast off! 🚀")

Output:

10...
9...
8...
7...
6...
5...
4...
3...
2...
1...
Blast off! 🚀

Breaking it down:

  • We start with countdown = 10
  • The loop checks countdown > 0 before every iteration
  • Inside the loop we print the number and subtract 1
  • When countdown hits 0 the condition becomes false and the loop stops
  • The final message prints after the loop ends

🎲 Random Numbers + While Loops — A Perfect Combo

Here's where while loops really shine — when you genuinely don't know how many times you'll need to loop.

Swift gives us a fantastic tool called random(in:) that generates a random number within a range:

let id = Int.random(in: 1...1000) // random Int between 1 and 1000
let amount = Double.random(in: 0...1) // random Double between 0 and 1

Now let's combine this with a while loop. Imagine you're playing a game and need to keep rolling a dice until you land a critical hit — a 20 on a 20-sided dice:

var roll = 0

while roll != 20 {
 roll = Int.random(in: 1...20)
 print("Rolled: \(roll)")
}

print("Critical hit! ⚔️")

Output (will vary every time):

Rolled: 7
Rolled: 13
Rolled: 4
Rolled: 19
Rolled: 20
Critical hit! ⚔️

Every time you run this code you'll get a different result — sometimes lucky, sometimes not. This is impossible to replicate cleanly with a for loop because you simply don't know how many rolls it will take. That's the whole point of while. 🎯


🎮 Another Example — Grinding for Power

Let's say you're building an RPG and a character needs to keep training until their power level hits 9000:

var powerLevel = 1
var trainingRounds = 0

while powerLevel < 9000 {
 let gainedPower = Int.random(in: 100...500)
 powerLevel += gainedPower
 trainingRounds += 1
 print("Round \(trainingRounds): Power level \(powerLevel)")
}

print("Power level is over 9000! 🔥 Took \(trainingRounds) rounds.")

Output (varies every run):

Round 1: Power level 342
Round 2: Power level 719
Round 3: Power level 1205
...
Power level is over 9000! 🔥 Took 21 rounds.

We have no idea how many rounds it will take — that's determined at runtime by the random numbers. A for loop just can't handle this kind of uncertainty. A while loop handles it perfectly. ✅


⚠️ Watch Out — Infinite Loops

One thing to be careful about with while loops — if your condition never becomes false, the loop runs forever and your app freezes. This is called an infinite loop:

// ⚠️ DON'T DO THIS
while true {
 print("This never stops!")
}

Always make sure something inside your loop will eventually make the condition false — like decrementing a counter or checking a value that will change. 🔒


🔁 The Repeat Loop — Always Run At Least Once

Swift has one more loop type that doesn't get talked about as much — the repeat loop. It's similar to while with one key difference:

A while loop checks its condition before running.
A repeat loop checks its condition after running — meaning it always runs at least once.

Here's the structure:

repeat {
 // code to run
} while condition

🤔 Why Does This Matter?

Let's say you want to shuffle an array of numbers and make sure the result is different from the original. With a regular while loop you'd write:

let numbers = [1, 2, 3, 4, 5]
var random = numbers.shuffled() // shuffle once here

while random == numbers {
 random = numbers.shuffled() // and again here if needed 😬
}

Notice the problem — numbers.shuffled() appears twice. That's unnecessary repetition. If that shuffle logic was more complex — say 10 or 20 lines — you'd be maintaining the same code in two places.

This is where the programming principle DRY comes in — Don't Repeat Yourself. Write code once, not twice. 🚫


✅ The Cleaner Way — repeat

Here's the same logic using repeat:

let numbers = [1, 2, 3, 4, 5]
var random: [Int]

repeat {
 random = numbers.shuffled()
} while random == numbers

print(random)

Much cleaner! The shuffle happens inside the loop body once, then the condition is checked. If the shuffled result matches the original, it shuffles again. If not, it stops. The shuffling code only exists once — no repetition, no maintenance headache. 🌸


🎮 Another Example — Generating a Unique Battle Code

let usedCodes = [1234, 5678, 9012]
var battleCode: Int

repeat {
 battleCode = Int.random(in: 1000...9999)
} while usedCodes.contains(battleCode)

print("Your unique battle code: \(battleCode) ⚔️")

The code runs at least once, generates a random number, then checks if it's already been used. If it has, it generates another. This guarantees we always get a fresh code — and the generation logic only lives in one place.


🆚 For vs While vs Repeat — Which to Use?

Situation Best choice
Looping over an array or set for loop
Looping a fixed number of times for loop
Looping until a condition is met while loop
Don't know how many iterations needed while loop
Need to run at least once, then check repeat loop
Avoiding duplicate code before a loop repeat loop

A simple way to think about it:

  • For loops — you know the finish line before you start 🏁
  • While loops — you run until something tells you to stop 🛑
  • Repeat loops — you run first, then decide whether to stop 🔄

🧩 Putting It All Together

Here's a mini battle system using all three concepts:

var health = 100
var bossHealth = 150
var round = 1

print("⚔️ Battle Start!")
print()

// While loop — keep fighting until someone loses
while health > 0 && bossHealth > 0 {
 let playerDamage = Int.random(in: 10...30)
 let bossDamage = Int.random(in: 5...20)

 bossHealth -= playerDamage
 health -= bossDamage

 print("Round \(round):")
 print(" You dealt \(playerDamage) — Boss health: \(max(0, bossHealth))")
 print(" Boss dealt \(bossDamage) — Your health: \(max(0, health))")
 print()

 round += 1
}

if health > 0 {
 print("🏆 You won in \(round - 1) rounds!")
} else {
 print("💀 Defeated in \(round - 1) rounds. Try again!")
}

// Repeat loop — generate a unique reward code
let usedCodes = [1111, 2222, 3333]
var rewardCode: Int

repeat {
 rewardCode = Int.random(in: 1000...9999)
} while usedCodes.contains(rewardCode)

print("🎁 Your reward code: \(rewardCode)")

🌟 Wrap Up

Now you know all three loop types in Swift:

  • for — when you know exactly how many times to loop
  • while — when you loop until a condition becomes false, checked before each run
  • repeat — when you always need at least one run, condition checked after

And remember — always make sure your while or repeat condition will eventually become false, or you'll end up with an infinite loop! 🔒

Next up we'll look at how to skip loop iterations and exit loops early using continue and break. See you there! 👋