Key-path (key path) is a mechanism for safe access to object properties "by reference". They provide full type-safe access for referencing properties:
struct Person { var name: String var age: Int } let kp = \Person.name let john = Person(name: "John", age: 30) print(john[keyPath: kp]) // "John"
WritableKeyPath allows not only reading but also modifying properties:
var person = Person(name: "Foo", age: 22) let namePath: WritableKeyPath<Person, String> = \Person.name person[keyPath: namePath] = "Bar"
Usage:
Nuances:
WritableKeyPath, the object (struct) must be var.Question: "Can class properties be changed through a regular KeyPath (or is WritableKeyPath required)? What is the difference between KeyPath and ReferenceWritableKeyPath?"
Answer: To change a property value via key path, a WritableKeyPath is required. For classes, there is also ReferenceWritableKeyPath, which allows changing properties by key-path for reference types.
class User { var score = 0 } let user = User() let path: ReferenceWritableKeyPath<User, Int> = \User.score user[keyPath: path] = 42 // OK
Story
In a large table-driven UI project, regular KeyPath and WritableKeyPath were confused — an attempt was made to change a model property via KeyPath, resulting in a runtime exception.
Story
When generating generic forms, KeyPath was used to bind values, but there was an attempt to reflect methods as keypaths, which led to compilation failure and code complexity.
Story
A developer forgot to add ReferenceWritableKeyPath for classes, which hindered bidirectional binding between UI and the data model: values were updated in the UI, but the model remained unchanged.