ProgrammingiOS Developer

What are key-paths in Swift? How to use WritableKeyPath and why are they needed, what problems do they solve, what pitfalls exist when working with the KeyPath API?

Pass interviews with Hintsage AI assistant

Answer.

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:

  • Used for generalized work with models (e.g., during sorting, filtering, data binding with UI).
  • Convenient for building user-friendly reflection without losing type safety.

Nuances:

  • KeyPath is only for properties that can be accessed by the compiler.
  • KeyPath cannot store methods, only properties.
  • For WritableKeyPath, the object (struct) must be var.

Trick Question.

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

Examples of real errors due to lack of knowledge of the nuances of the topic.


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.