๐ŸŽ“ A1Learner
๐Ÿ”
0 of 36 lessons completed

Swift Trailing Closures

A function can end with more than one closure parameter. The call places the first closure after the parentheses and labels each closure after it.

Two trailing closures

The function takes a name and two closures. The call writes the first closure after the parentheses and labels the second one footer.

func buildProfile(name: String, header: () -> Void, footer: () -> Void) {
    print(name)
    header()
    footer()
}
buildProfile(name: "Ana") {
    print("Welcome")
} footer: {
    print("Goodbye")
}

A trailing closure beside other arguments

The text and the count stay inside the parentheses. The single closure moves outside and still receives each word in turn.

func repeatPrint(_ text: String, times: Int, decorate: (String) -> String) {
    for _ in 1...times {
        print(decorate(text))
    }
}
repeatPrint("swift", times: 2) { word in
    "[" + word + "]"
}

A pair that repeats

The function runs its two closures in turn for each round. The labelled second closure keeps the pair easy to read.

func perform(count: Int, first: () -> Void, second: () -> Void) {
    for _ in 1...count {
        first()
        second()
    }
}
perform(count: 2) {
    print("open")
} second: {
    print("close")
}

Example

func runTask(name: String, success: () -> Void, failure: () -> Void) {
    if name.isEmpty {
        failure()
    } else {
        print(name)
        success()
    }
}
runTask(name: "Upload") {
    print("done")
} failure: {
    print("failed")
}
runTask(name: "") {
    print("done")
} failure: {
    print("failed")
}

Key points

  • A trailing closure sits outside the parentheses of a call.
  • A call can carry several trailing closures one after another.
  • Only the first trailing closure goes without a label.
  • Each later trailing closure uses its parameter label.
  • Other arguments still sit inside the parentheses in the usual way.
  • The closures run in the order the function body calls them.

In this example, runTask receives a name and two closures written as trailing closures. The first call has a name, so it prints Upload and runs the success closure. The second call has an empty name, so it runs the failure closure and prints failed.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

How does a call write the second of two trailing closures?