In This Article
So far, your code has been linear — it runs from top to bottom, every line, every time. Real programs need to make decisions: do one thing when a user taps "Buy", something else when they tap "Cancel". They also need to repeat work: process every item in a shopping cart, retry a failed network request, animate a loading spinner.
This is control flow — the mechanisms that control which code runs and how many times. This chapter covers the foundations: Booleans for representing truth, comparison operators for testing conditions, if statements for making decisions, and while loops for repeating work.
Booleans: True and False
Swift has a type called Bool (short for Boolean, named after mathematician George Boole) that can only hold one of two values: true or false.
Booleans are the foundation of every decision your code makes. Every if statement, every loop condition, every toggle in your UI — all built on Booleans.
You can flip a Boolean's value with the toggle() method:
Comparison Operators
You rarely create Booleans by writing true or false directly. Instead, they come from comparisons:
Each comparison produces a Bool. The ! prefix operator (the NOT operator) flips any Boolean:
Boolean Logic: AND, OR, NOT
Single comparisons are useful, but real decisions often depend on multiple conditions. Swift provides two operators for combining Booleans:
AND (&&) — both must be true
If either input is false, the result is false. You need a ticket AND an ID to enter.
OR (||) — at least one must be true
Only if both inputs are false does the result become false.
Combining conditions
You can chain these together. Use parentheses to make the logic clear:
Comparing Strings
You can compare strings with the same operators you use for numbers:
The < and > operators compare strings alphabetically. This is useful for sorting and searching.
Making Decisions With if
The if statement is how your program makes decisions. If a condition is true, run this code. Otherwise, skip it.
The code inside the braces only runs if temperature > 30 is true. If it's false, Swift skips it entirely.
Adding else
You often want to do something different when the condition is false:
Chaining Conditions With else-if
When you have multiple possible outcomes, chain conditions with else if:
Swift checks each condition from top to bottom and runs the first one that's true. Once a match is found, it skips all remaining conditions. This means order matters — put more specific conditions first.
If you checked hour < 21 before hour < 17, the value 14 would match "Good evening" instead of "Good afternoon". Always order your conditions from most specific to least specific.
Short-Circuit Evaluation
Swift is smart about evaluating Boolean expressions. With &&, if the first condition is false, Swift doesn't bother checking the second — the result is already false. With ||, if the first condition is true, Swift skips the second — the result is already true.
This is called short-circuit evaluation. It's not just an optimization — it lets you write safe conditions where the second check depends on the first being true.
Variable Scope
Every pair of braces {} creates a new scope. Variables and constants declared inside a scope only exist within that scope:
The constant bonus was created inside the if block's scope and dies when that scope ends. But code inside a scope can access variables from its parent scope — that's how total gets modified.
This scoping rule prevents variables from leaking into places they shouldn't be and keeps your code clean.
The Ternary Operator
For simple "if this, then that, otherwise the other thing" decisions, Swift has a one-line shorthand called the ternary conditional operator:
This replaces a 5-line if/else block with a single expression. Use it when the logic is simple and fits on one line. For anything more complex, stick with if/else — readability always wins.
Finding the smaller or larger of two values is so common that Swift provides min(a, b) and max(a, b) functions. Use them instead of writing your own ternary for this purpose.
While Loops
A while loop repeats a block of code as long as a condition remains true:
The loop checks the condition before each iteration. If the condition is false from the start, the body never runs.
If the condition never becomes false, the loop runs forever. Always make sure something inside the loop changes the condition — like incrementing a counter or modifying the value being tested.
Repeat-While Loops
A repeat-while loop is similar, but it checks the condition after each iteration. This guarantees the body runs at least once:
This keeps rolling a die until you get a 6. Because it's repeat-while, you always roll at least once — even if the first roll is a 6.
When to use which
- while — when the loop might not need to run at all (check first)
- repeat-while — when the loop must run at least once (act first, check after)
Breaking Out of Loops
Sometimes you need to exit a loop early. The break statement immediately stops the loop:
This pattern — a while true loop with a break condition inside — is useful when the exit condition is complex or appears in the middle of the loop body rather than at the top or bottom.
Exercises
Try These in Your Playground
- Create a constant
myAgeset to your age. Use anifstatement to print "Teenager" if the age is between 13 and 19 (inclusive), or "Not a teenager" otherwise. - Rewrite exercise 1 using the ternary operator to set a constant
statusto either "Teenager" or "Not a teenager", then print it. - Create a
whileloop that counts from 0 to 9, printing each number. - Create a
repeat-whileloop that simulates rolling a die (Int.random(in: 1...6)) until you roll a 1. Count and print how many rolls it took. - Evaluate these Boolean expressions by hand, then verify in a playground:
•true && true
•false || false
•(true && 1 != 2) || (4 > 3 && 100 < 1)
•((10 / 2) > 3) && ((10 % 2) == 0) - Challenge: Write a program that calculates the nth Fibonacci number using a
whileloop. The sequence starts 1, 1, 2, 3, 5, 8, 13...
Key Points
What You Learned
Boolrepresentstrueorfalse; use.toggle()to flip the value- Comparison operators:
==!=<><=>= &&(AND) requires both conditions true;||(OR) requires at least one!(NOT) flips a Boolean value- Strings can be compared with
==,<,>for equality and alphabetical order if/else if/elselets you branch based on conditions- Conditions are checked top-to-bottom; only the first true branch executes
- Short-circuit evaluation skips unnecessary checks in
&&and||expressions - Variables declared inside braces
{}are scoped to that block - The ternary operator
condition ? a : bis a one-line if/else whileloops check the condition before each iterationrepeat-whileloops check after — guaranteeing at least one executionbreakexits a loop immediately
In the next chapter, we'll cover Advanced Control Flow — for-in loops for iterating over ranges and collections, switch statements for powerful pattern matching, and the continue keyword.
Watch the video lessons
Our Swift Fundamentals course covers control flow, Boolean logic, switch statements, and real-world challenges in 96 video lessons.
Watch Swift Videos