Where are closures typically used in app development?

I recently began studying closures and while i believe I understand the theory, I am having trouble understand or imagining how these would be used real life app development.

Could someone please provide me with a practical, beginner-friendly example of cases in app development in which closures would be used, preferred, or beneficial?

Thank you.

I'm pretty sure I had trouble understanding closures at some point, too. Maybe the simplest app-related example is something like using a closure to perform an action when you tap a button:

Button("Say Hello") {
    print("Hello")
}

The closure in that example is the portion of code in the brackets ({ }).


There's a more complicated definition for the term closure that isn't as simple as being an unnamed function. If that's what you're interested in, post back here and we can examine that too.

1 Like

One pattern that seems to be popular is to use closures to keep cause and effect code close to each other in the source, so that it’s easier to link them mentally. Even though they’re not necessarily executed close to each other in terms of real-time.

E.g. Timers: Timers are a way or getting a specific bit of code executed at a specific time (as in wall-clock time). The classic way of doing this was via a callback function - so you define the code you wanted executed at that future time in a function (or method) and pass a reference to that function to a timer object. The timer would then invoke that function at the appropriate time.

Because the code to be executed was in a separate function is was necessarily distant (in the source file) from the code that would cause it to be invoked.

Closures allow you to define that function directly as an argument when instantiating the timer so you can see inline what the timer will do when triggered.

This is also applicable to Notifications, network requests and other asynchronous events.

2 Likes

e.g. (pseudo code. Will not work. Excuse errors, I’m more familiar with Obj-C than Swift)

let fooTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: NSSelectorFromString("timerFired"), userInfo: nil, repeats: false)

func timerFired() {
    print("timer fired")
}

Versus

let barTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false, block: {_ in print("timer fired")})

Look up map(), filter(), reduce(), first(where:, sort(by: and other methods in the standard library that use closures. These are different from the network, timer and other kinds of callbacks that are async. Apple's docs give simple example code.

2 Likes

This. The most common use of closures is as arguments to higher-order functions.

If there's a named function for what you need there, use it. If you'll use the same code twice, write a function. Otherwise, for one-shot only use, use a closure.

1 Like

In a very naive regex search through my current project, I've found at least 291 closures (I only counted the closures of the form where I have and use named input arguments, like { args in, and not the implicit ones like { someFunction($0) }, or void-closures, so there are at least that many)

The vast majority of those are .maps, .flatMaps, but there are also a large number of network request callbacks and other async operations. Also some button event handlers.

This is a pretty normal project I'd say.

Thank you very much everyone for these responses. The Timer example is especially helpful since I've used this before in my app dev practice. Thank you!