Bird
Raised Fist0
iOS Swiftmobile~20 mins

Functions and closures in iOS Swift - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Greeting Screen
This screen lets the user enter their name and then shows a greeting message using a function and a closure.
Target UI
-------------------------
| Greeting Screen       |
|-----------------------|
| Enter your name:      |
| [______________]      |
|                       |
| [Greet Me]            |
|                       |
| Greeting:             |
|                       |
|                       |
-------------------------
Add a TextField for user to enter their name.
Add a Button labeled 'Greet Me'.
When the button is tapped, use a function that takes the name and a closure.
The function should create a greeting message and pass it to the closure.
The closure updates the greeting label with the message.
The greeting label shows 'Hello, [name]!' after tapping the button.
Starter Code
iOS Swift
import SwiftUI

struct GreetingScreen: View {
    @State private var name: String = ""
    @State private var greetingMessage: String = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("Greeting Screen")
                .font(.title)

            TextField("Enter your name", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(.horizontal)

            Button("Greet Me") {
                // TODO: Call greet function with name and closure
            }

            Text("Greeting:")
                .font(.headline)

            Text(greetingMessage)
                .font(.largeTitle)
                .foregroundColor(.blue)

            Spacer()
        }
        .padding()
    }

    // TODO: Add greet function here
}

struct GreetingScreen_Previews: PreviewProvider {
    static var previews: some View {
        GreetingScreen()
    }
}
Task 1
Task 2
Task 3
Task 4
Solution
iOS Swift
import SwiftUI

struct GreetingScreen: View {
    @State private var name: String = ""
    @State private var greetingMessage: String = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("Greeting Screen")
                .font(.title)

            TextField("Enter your name", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(.horizontal)

            Button("Greet Me") {
                greet(name) { message in
                    greetingMessage = message
                }
            }

            Text("Greeting:")
                .font(.headline)

            Text(greetingMessage)
                .font(.largeTitle)
                .foregroundColor(.blue)

            Spacer()
        }
        .padding()
    }

    func greet(_ name: String, completion: (String) -> Void) {
        let message = "Hello, \(name)!"
        completion(message)
    }
}

struct GreetingScreen_Previews: PreviewProvider {
    static var previews: some View {
        GreetingScreen()
    }
}

We created a function greet that takes a name and a closure called completion. Inside the function, it builds a greeting message using the name, then calls the closure with that message. The button calls greet passing the current name and a closure that updates the greetingMessage state. This updates the UI to show the greeting. This shows how functions and closures work together to handle data and update the screen.

Final Result
Completed Screen
-------------------------
| Greeting Screen       |
|-----------------------|
| Enter your name:      |
| [Alice__________]     |
|                       |
| [Greet Me]            |
|                       |
| Greeting:             |
|                       |
| Hello, Alice!         |
-------------------------
User types their name in the text field.
User taps the 'Greet Me' button.
The greeting label updates to say 'Hello, [name]!'.
Stretch Goal
Add a Clear button that resets the name and greeting message to empty strings.
💡 Hint
Add another Button labeled 'Clear' below the 'Greet Me' button. In its action, set both name and greetingMessage to "".

Practice

(1/5)
1. What is a closure in Swift?
func greet() { print("Hello") }
easy
A. An unnamed block of code that can be stored and passed around
B. A named function that cannot be reused
C. A variable that holds a number
D. A type of loop

Solution

  1. Step 1: Understand closure definition

    A closure is a block of code without a name that can be saved and used later.
  2. Step 2: Compare with function

    Functions have names, closures do not but both can be reused.
  3. Final Answer:

    An unnamed block of code that can be stored and passed around -> Option A
  4. Quick Check:

    Closure = unnamed reusable code block [OK]
Hint: Closures are like functions without names [OK]
Common Mistakes:
  • Confusing closures with variables
  • Thinking closures must have names
  • Mixing closures with loops
2. Which of the following is the correct syntax to declare a closure that takes no parameters and returns an Int?
easy
A. let closure = (Int) -> { return 5 }
B. let closure = { () -> Int in return 5 }
C. let closure = func() -> Int { return 5 }
D. func closure() -> Int { return 5 }

Solution

  1. Step 1: Identify closure syntax

    Closures use curly braces with parameters and return type before 'in'.
  2. Step 2: Check each option

    'let closure = { () -> Int in return 5 }' matches closure syntax. 'func closure() -> Int { return 5 }' declares a named function. 'let closure = func() -> Int { return 5 }' uses invalid syntax. 'let closure = (Int) -> { return 5 }' lacks 'in' keyword and has wrong parameter placement.
  3. Final Answer:

    let closure = { () -> Int in return 5 } -> Option B
  4. Quick Check:

    Closure syntax = curly braces + 'in' [OK]
Hint: Closures use braces and 'in' keyword [OK]
Common Mistakes:
  • Using func keyword inside closure
  • Missing 'in' keyword
  • Wrong parameter syntax
3. What will be printed by this Swift code?
let multiply = { (a: Int, b: Int) -> Int in
  return a * b
}
print(multiply(3, 4))
medium
A. 34
B. 7
C. 12
D. Error

Solution

  1. Step 1: Understand closure parameters and return

    The closure takes two Ints and returns their product.
  2. Step 2: Calculate multiply(3, 4)

    3 * 4 equals 12, so print outputs 12.
  3. Final Answer:

    12 -> Option C
  4. Quick Check:

    3 times 4 = 12 [OK]
Hint: Closures return calculated values like functions [OK]
Common Mistakes:
  • Adding instead of multiplying
  • Concatenating numbers as strings
  • Syntax errors in closure call
4. Identify the error in this closure declaration:
let add = { (a: Int, b: Int) Int in
  return a + b
}
medium
A. Missing '->' before return type
B. Missing 'in' keyword
C. Parameters should not have types
D. Closure cannot return Int

Solution

  1. Step 1: Check closure signature syntax

    Return type must be preceded by '->' in closure signature.
  2. Step 2: Identify missing arrow

    Code has '(a: Int, b: Int) Int' but should be '(a: Int, b: Int) -> Int'.
  3. Final Answer:

    Missing '->' before return type -> Option A
  4. Quick Check:

    Closure return type needs '->' [OK]
Hint: Return type needs '->' before it in closures [OK]
Common Mistakes:
  • Omitting '->' in closure signature
  • Placing 'in' incorrectly
  • Removing parameter types
5. You want to sort an array of names alphabetically using a closure. Which code correctly uses a closure with the sorted(by:) method?
hard
A. let sortedNames = names.sorted(by: { s1, s2 -> Bool { return s1 > s2 } })
B. let sortedNames = names.sorted(by: { s1, s2 in s1 + s2 })
C. let sortedNames = names.sorted(by: (s1, s2) -> s1 < s2)
D. let sortedNames = names.sorted(by: { s1, s2 in s1 < s2 })

Solution

  1. Step 1: Understand sorted(by:) closure

    It expects a closure that returns true if first element should come before second.
  2. Step 2: Check each option

    'let sortedNames = names.sorted(by: { s1, s2 in s1 < s2 })' returns true when s1 < s2 (correct for ascending alphabetical order). The version with s1 > s2 sorts descending. The version with (s1, s2) -> s1 < s2 uses invalid syntax without braces or 'in'. The version with s1 + s2 returns String, not Bool.
  3. Final Answer:

    let sortedNames = names.sorted(by: { s1, s2 in s1 < s2 }) -> Option D
  4. Quick Check:

    sorted(by:) needs Bool-returning closure [OK]
Hint: sorted(by:) needs closure returning true/false [OK]
Common Mistakes:
  • Returning wrong type from closure
  • Using wrong comparison operator
  • Incorrect closure syntax
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard