This article has been archived, as it was published several years ago, so some of its information might now be outdated. For more recent articles, please visit the main article feed.
Limiting collection mutations
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()
}
}
}

Swift by Sundell is brought to you by the Genius Scan SDK — Add a powerful document scanner to any mobile app, and turn scans into high-quality PDFs with one line of code. Try it today.