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

Limiting collection mutations

Published on 05 Sep 2019

When designing APIs, we often want to limit the amount of mutations that any object can perform, since doing so tends to both make our code more robust — and can also make our APIs easier to understand.

One way to do that when working with collections is to keep the way we store values private, and instead only expose a more limited mutating API.

For example, this collection of Warning values can only be mutated by appending elements — it’s not possible for any external object to remove or mutate existing values:

public extension Warning {
    // By conforming to Sequence, our collection can be mapped, filtered,
    // and iterated over in many other ways - just like an array:
    struct Collection: Sequence {
        private var warnings = [Warning]()

        // We only want our API users to be able to append warnings
        // to this collection, so we only expose that method as
        // part of our public API:
        public mutating func append(_ warning: Warning) {
            warnings.append(warning)
        }

        // Here we reuse Array's iterator type, to avoid having to
        // create our own, and to keep all of Array's behaviors:
        public func makeIterator() -> Array<Warning>.Iterator {
            return warnings.makeIterator()
        }
    }
}

Support Swift by Sundell by checking out this sponsor:

Emerge

Emerge: Continuously monitor and reduce your app’s size. Emerge’s easy to use plugins for GitHub and fastlane will automatically scan your app’s binary and provide you with simple, actionable suggestions on how to make it smaller and, in turn, faster for your users to download. Set up a demo now!