Articles, podcasts and news about Swift development, by John Sundell.

Attaching property wrappers to function arguments

Published on 23 Jul 2021
Basics article available: Properties

New in Swift 5.5: Property wrappers can now be applied directly to function arguments, just like how they can be used to add additional functionality to a property or local variable.

For example, let’s say that an app that we’re working on contains a function that saves a Photo for a given name, and that we always want to normalize each name by lowercasing it. One way to do that would be to override the passed name argument using a local property — like this:

func savePhoto(_ photo: Photo, named name: String) {
    let name = name.lowercased()

There’s certainly nothing wrong with the above approach, but let’s take a look at how we could now use a property wrapper to instead embed our lowercasing transformation into the function argument itself.

To get started, let’s create a Lowercased property wrapper, which automatically lowercases any String value that was assigned to it:

@propertyWrapper struct Lowercased {
    var wrappedValue: String {
        didSet {
            wrappedValue = wrappedValue.lowercased()

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue.lowercased()

Then, we can now attach our new Lowercased wrapper directly to our name argument, which will ensure that its value will always be lowercased, without requiring that transformation to happen inline within our function’s main body:

func savePhoto(_ photo: Photo, @Lowercased named name: String) {

Pretty neat! Even property wrappers that accept arguments of their own can be attached using the above technique. For example, the following Truncated wrapper automatically truncates its wrapped collection so that it only contains a certain number of elements:

@propertyWrapper struct Truncated<Value: RangeReplaceableCollection> {
    var wrappedValue: Value {
        didSet { wrappedValue = Value(wrappedValue.prefix(maxLength)) }
    var maxLength: Int

    init(wrappedValue: Value, maxLength: Int) {
        self.wrappedValue = Value(wrappedValue.prefix(maxLength))
        self.maxLength = maxLength

With the above in place, we can now easily truncate any collection-based function argument simply by attaching our new Truncated wrapper to it — like this:

func updateFavorites(@Truncated(maxLength: 20) to favorites: [Item]) {

While this new feature doesn’t really provide us with any revolutionary new ways to write Swift code, it does add an extra degree of consistency to Swift’s overall property wrappers system — since wrappers can now be applied to properties, local variables, and function arguments, all with the same kind of functionality.

Support Swift by Sundell by checking out this sponsor:


Instabug: Whether it’s crashes, slow screen transitions, delayed network calls, or unresponsive UIs — Instabug automatically gives you all of the logs you need to fix bugs and issues, and to ship high-quality apps. Get started now.