When SwiftUI launched at WWDC 2019, the Apple developer community was taken by surprise. Throughout the week, WWDC sessions continued to delight developers in attendance, but many on-site (and beyond) were a touch confused by SwiftUI's use of the ‘$’ prefix in code. If that sounds like you, here’s a primer on what that new dollar-sign prefix is all about.
Let’s start with the core of SwiftUI, which is the view. In its most direct form, SwiftUI allows you to drag and drop things onto your view, much as you can in Xcode storyboards now. The difference is it will also return usable code in your
.swift files, which is where manipulation of those views can occur.
As an example, let’s just say you have a single-view app for ordering a sandwich. In your view, there are options for things such as type of bread, condiments, meats, produce (lettuce, tomatoes, etc.), as well as add-ons such as avocado or bacon. At the bottom of your view, there’s an Apple Pay button that completes the order. Simple.
You would likely want to store the functionality of your sandwich app in a different file, just to keep things nice and clean. It’s where you would have functions for the types of bread, meats, add-ons, and other items people can get on their sandwich. The Apple Pay API may go in its own file.
Now you’ve got three files: Your view, a
.swift file for the logic of your app, and one for the Apple Pay API. We don’t need to worry about the Apple Pay API for this example, but the
.swift file and view are important.
Let’s say you have a unique Struct for bread, with five different types of bread for customers to choose from. In the app’s view, where the customer chooses their bread, your code for that view would include something like
$typeOfBread in the selector. A ‘$’ prefix is a read-write binding, which means your view is calling back to your
.swift Struct for the bread types it can access.
We first see the ‘$’ discussed in Swift Evolution 258:
The use of the prefix $ for the synthesized storage property name is deliberate: it provides a predictable name for the backing storage, so that wrapper types can provide API.
And from Apple’s documentation regarding bindings:
Bindings are considered to be a property of the object which is bound, and all information related to bindings should be owned by the object.
The view of your imagined app makes no assumptions; it just saves the request until the customer pays and the order is submitted. It’s the same concept as sitting in a restaurant and ordering a sandwich on rye bread, then asking your server to switch to wheat bread. The server wrote down rye, but simply crossed that out and wrote “wheat” instead. Nothing was finalized until the server sent your sandwich order to the kitchen.
(And if you said "brioche" and the restaurant didn't have that type of bread, your server would let you know. In your app's view, you may want to choose a selector wheel for the bread types available.)
So it is with your view. The ‘$’ prefix holds the selection in place within your view until the order is completed. It calls back to the Struct as a read-write binding, because the order isn’t finalized until it is completed via the Apple Pay button, and the user may change their mind.
The ‘$’ prefix is new, and a bit intimidating if you’ve not used it before – but it’s also really handy. We like it because it keeps your view code from being too long-winded, and it almost forces developers into the practice of creating new files for various aspects of their code (logic, view, Apple Pay API, etc.).
If you’re not yet running Xcode 11 with SwiftUI and the macOS Catalina beta, you can tinker with ‘$’ prefixes in Xcode Playgrounds. The ‘$’ prefix is used in Swift for implicitly naming parameters in closures where parameters have no names, which is described in the “Expressions” section of Language Reference on Swift.org.