Ultimate Guide to Swift Control Flow: Mastering If Statements, Loops, and Early Exits

Amitesh Mani Tiwari
7 min readAug 3, 2024

--

“Coding is like riding a bike: control the flow, and you’ll never fall.”

AppDevByAmitesh

Hey there, tech enthusiasts! 👋 I’m Amitesh Mani Tiwari, a Software Engineer (iOS Team) at Angel One📈 with 2.5 years of experience. Over the years, I’ve delivered 35+ tech and non-tech talks 🎤, mentored at hackathons 👨‍💻, and impacted over 9000 students. Oh, and I was also honored as a 21U21 Award Winner! 💖

Before we dive into the Swift control flow, make sure to check out my previous blogs:

  1. Swift Collections Unleashed: Comprehensive Insights into Arrays, Sets, and Dictionaries
  2. Mastering Swift Basics: A Guide to Variables, Constants, and Data Types

These will give you a solid foundation to build upon as we explore control flow in Swift.

Ami’s Swift Journey with Siri: Control Flow Edition 🛤️

Ami: Hey Siri, I’ve mastered Swift collections. What’s the next step in my Swift journey?

Siri: Ami, it’s time to master control flow! Let’s dive into if statements, loops, and early exits to make your code more efficient and dynamic.

Ami: Sounds like a plan! Control flow is like the GPS of coding, right?

Siri: Exactly! Without control flow, you’d be coding blindfolded. Let’s get started!

Understanding Control Flow in Swift

Control flow in Swift allows you to direct the execution of your code based on certain conditions and repeatedly execute blocks of code. This is essential for making decisions, iterating over data, and managing the flow of your application efficiently.

For-In Loops

For-in loops allow you to iterate over a sequence, such as arrays, dictionaries, ranges, or strings.

Imagine you’re a chef preparing a list of dishes for a dinner party. You have an array of dishes, and you need to print each one to ensure everything is accounted for:

let dishes = ["Salad", "Soup", "Pasta", "Dessert"]
for dish in dishes {
print("Preparing \(dish)!")
}
// Output:
// Preparing Salad!
// Preparing Soup!
// Preparing Pasta!
// Preparing Dessert!

You can also iterate over a dictionary to access its key-value pairs. Think of it like checking the ingredients in your pantry, where each item has a name and a quantity:

let pantry = ["Flour": "2 kg", "Sugar": "1 kg", "Eggs": "12 pieces"]
for (ingredient, quantity) in pantry {
print("We have \(quantity) of \(ingredient)")
}
// Output:
// We have 2 kg of Flour
// We have 1 kg of Sugar
// We have 12 pieces of Eggs

While Loops

While loops execute a set of statements as long as a condition is true.

Imagine you’re jogging and want to count your steps until you reach your daily goal. You keep jogging until you’ve taken enough steps:

While Loop

var steps = 0
let goal = 10000
while steps < goal {
print("Keep going, you've taken \(steps) steps!")
steps += 1000
}
// Output:
// Keep going, you've taken 0 steps!
// Keep going, you've taken 1000 steps!
// ...
// Keep going, you've taken 9000 steps!

Repeat-While Loop

The repeat-while loop evaluates its condition after executing the loop’s code block.

var reps = 1
repeat {
print("Completed \(reps) repetitions")
reps += 1
} while reps <= 5
// Output:
// Completed 1 repetitions
// Completed 2 repetitions
// ...
// Completed 5 repetitions

Conditional Statements

If statements execute code based on a condition.

Imagine you’re deciding what to wear based on the temperature:

let temperature = 30
if temperature > 25 {
print("It's a hot day! Wear light clothes.")
} else {
print("It's a cool day! Wear something warm.")
}
// Output:
// It's a hot day! Wear light clothes.

Switch statements compare a value against multiple patterns.

Imagine you’re planning a trip and need to check the day of the week to decide your activities:

let day = "Saturday"
switch day {
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
print("It's a weekday. Time to work!")
case "Saturday", "Sunday":
print("It's the weekend! Time to relax.")
default:
print("What day is it?")
}
// Output:
// It's the weekend! Time to relax.

Control transfer statements change the order of code execution. Swift includes continue, break, fallthrough, return, and throw.

Continue

The continue statement tells a loop to stop what it’s doing and start again at the beginning of the next iteration.

Imagine you’re reading a list of books but want to skip over any book that’s already read:

let books = ["Book A", "Book B", "Book C", "Book D"]
let readBooks = ["Book B", "Book D"]
for book in books {
if readBooks.contains(book) {
continue
}
print("Reading \(book)")
}
// Output:
// Reading Book A
// Reading Book C

Break

The break statement ends the execution of an entire control flow statement immediately.

Imagine you’re at a buffet, trying different dishes, but you want to stop once you find your favorite:

let dishes = ["Salad", "Soup", "Pasta", "Pizza"]
let favorite = "Pasta"
for dish in dishes {
if dish == favorite {
print("Found my favorite: \(dish)!")
break
}
print("Trying \(dish)")
}
// Output:
// Trying Salad
// Trying Soup
// Found my favorite: Pasta!

Fallthrough

The fallthrough keyword causes code execution to continue to the next case in a switch statement.

Imagine you’re categorizing a score and you want to add additional comments if the score is very high:

let score = 85
var description = "Score: \(score) is"
switch score {
case 0..<50:
description += " below average."
case 50..<75:
description += " average."
fallthrough
case 75..<100:
description += " above average."
fallthrough
default:
description += " an excellent performance!"
}
print(description)
// Output:
// Score: 85 is above average. an excellent performance!

Labeled Statements

Labeled statements can be used with break and continue to specify which loop or conditional statement you want to affect.

Imagine you’re in a treasure hunt game with nested loops for different regions and locations, and you want to break out of both loops once you find the treasure:

let regions = ["Forest", "Desert"]
let locations = ["Cave", "Oasis", "Mountain"]
outerLoop: for region in regions {
for location in locations {
if location == "Oasis" && region == "Desert" {
print("Found the treasure at the \(location) in the \(region)!")
break outerLoop
}
print("Searching \(location) in the \(region)")
}
}
// Output:
// Searching Cave in the Forest
// Searching Oasis in the Forest
// Searching Mountain in the Forest
// Searching Cave in the Desert
// Found the treasure at the Oasis in the Desert!

Early Exits

Guard statements transfer control out of a scope if conditions aren’t met.

Imagine you’re organizing a party and you need to check if all necessary preparations are done:

func organizeParty(preparations: [String: String]) {
guard let venue = preparations["venue"] else {
print("No venue selected, can't organize the party.")
return
}

guard let date = preparations["date"] else {
print("No date set, can't organize the party.")
return
}

print("Party is organized at \(venue) on \(date).")
}
organizeParty(preparations: ["venue": "Beach", "date": "Saturday"])
// Output:
// Party is organized at Beach on Saturday.

Deferred Actions

Defer blocks execute code just before the current scope exits.

Imagine you’re writing a report and want to ensure you save your work before you close the document:

func writeReport() {
print("Start writing report")
defer {
print("Saving the report")
}
print("Writing content")
// Defer block will execute here, before the function exits
}
writeReport()
// Output:
// Start writing report
// Writing content
// Saving the report

Checking API Availability

Swift’s built-in API availability checks ensure you don’t use unavailable APIs for a given deployment target.

Imagine you’re developing an app and want to use features available only in the latest iOS:

if #available(iOS 15, *) {
// Use iOS 15 features
print("Using iOS 15 features")
} else {
// Fallback for older versions
print("Using fallback features")
}
// Output will depend on the iOS version

Join the Conversation 💬

  • Share Your Journey: Comment below with your experiences learning Swift. What projects have you worked on?
  • Follow for More: Stay tuned for more in-depth articles and tutorials on Swift development.
  • Spread the Word: Share this post with fellow developers to spread the knowledge and excitement about Swift!

Conclusion 🎉

Ami: Wow, Siri! Understanding control flow really makes coding much more dynamic and efficient. I feel like I can control my code better now!

Siri: Absolutely, Ami! Control flow is crucial for directing your code to do exactly what you want, when you want it. Remember, coding without control flow is like trying to navigate a maze with your eyes closed.

Ami: And nobody likes bumping into walls! Thanks, Siri. Can’t wait to see what’s next.

Siri: Stay tuned, Ami! The journey continues, and the next adventure in Swift will be just as exciting.

Ami: Looking forward to it! And to all my fellow developers, keep coding and keep controlling your flow!

Connect with Me 🤝

Let’s connect and grow together! 🚀

--

--

Amitesh Mani Tiwari
Amitesh Mani Tiwari

Written by Amitesh Mani Tiwari

Software Engineer (iOS Team) @Angel One📈 | ex Upstox 35+ Tech/Non-Tech Talks 🎤 | 👨‍💻 Impacting 9000+ Students | 21U21 Award Winner 💖 iOS Developer

No responses yet