Prototype
Prototype creates a new object from an existing configured example. Swift value types make the common case simple: assigning a struct copies its value, including its value-type members.
iOS problem and when to use it
A dashboard editor offers a saved layout as a starting point. The user should be able to duplicate it, change widgets, and leave the original untouched. Prototype is useful when setup is expensive or there are many configuration fields to preserve.
Original example: duplicate a dashboard preset
import Foundation
struct Widget: Identifiable {
let id: UUID
var kind: String
var isVisible: Bool
}
struct DashboardPreset {
let id: UUID
var name: String
var widgets: [Widget]
func duplicated(as newName: String) -> DashboardPreset {
DashboardPreset(
id: UUID(),
name: newName,
widgets: widgets.map {
Widget(id: UUID(), kind: $0.kind, isVisible: $0.isVisible)
}
)
}
}
let original = DashboardPreset(
id: UUID(), name: "Morning",
widgets: [Widget(id: UUID(), kind: "Weather", isVisible: true)]
)
var copy = original.duplicated(as: "Weekend")
copy.widgets[0].isVisible = falseThe new preset and widgets get new identities, while their editable settings are copied. This matters if widgets are stored by ID in SwiftData, Core Data, or a server database.
Production decisions
Decide which fields are copied and which are regenerated: IDs, creation dates, and server ownership usually need new values. A plain let copy = original is sufficient when identity is intentionally shared or the type contains only value data. If a model contains class references, a shallow copy may still share mutable children; define an explicit deep-copy operation for those members.
Copy configuration, regenerate identity
DashboardPreset is a struct, so copying its value preserves settings without sharing mutable storage. But a persisted duplicate cannot reuse the original preset ID or widget IDs. duplicated(as:) explicitly creates new IDs while copying widget kind and visibility. That selective copying is the heart of this Prototype example: it uses an existing instance as the source of configuration while producing a distinct entity.
From example to a dashboard editor
The user taps Duplicate on a saved layout. The view model calls duplicated(as:), saves the result through a repository, and opens the new preset in the editor. If widgets have references to data sources or server records, decide whether those references should remain shared. A duplicated widget may need a new display identity but still point to the same weather location or calendar. Copying and identity rules are domain decisions, not automatic language behavior.
Failure modes and verification
Test that edits to the duplicate do not alter the original, that all IDs are unique, and that intended external references remain intact. If a nested field is a class instance, copying the outer struct still shares that reference. Implement deep copying or convert nested configuration to values when independent edits are required. A simple initializer is enough when there is little configuration to preserve.