What are Swift’s Keypaths?
By: Steven Curtis
Tags: Programming, Software Development, iOS, Swift Programming, Swift

What are Swift’s Keypaths?

They help with KVO and more!

Difficulty: Beginner | Easy | Normal | Challenging

This article has been developed using Xcode 11.4.1, and Swift 5.2.2

Prerequisites

You will be expected to be aware how to make a Single View Application, or a Playground to run Swift code

Terminology

keypath: Read-only access to a property

writablekeypath: read-write access to a value-type property

referencewritablekeypath: read-write access to a reference-type property

Motivation

Combine uses ReferenceWritableKeyPath<Root, Bool> in the assign function

which is the one that allows us to connect to UIKit elements, for example

That seems fine, but what are keypaths? How are they used, and what do they mean?

Could you make an article explaining this for me?

I don’t mind if I do!

What is a keypath?

A keypath provides read-only access to a property, whilst a writable keypath provides (well…) writable access to a property.

A keypath example

Perhaps the best way to describe this access is through an example, where we can set up a rather basic struct object.

we can then access the properties through WritableKeyPath<Person, String> or WritableKeyPath<Person, Int> (where firstname and secondname are represented by a String and age is represeted by a Int ).

The following keypath therefore returns a String , and that can be printed out

Now even the property type can be stored

which means that you can potentially use the same property in multiple places, and storing it as a property itself means that it would only need to be stored in one place.

Nested properties

The following is an example of nested keypaths

KeyPath composition

Swift allows you to dynamically combine keypaths at runtime (of course the types need to be compatible).

KeyPaths as type-erased variants

You may wish to have a keypath that does not require the Value parameter

So both drawerName and drawerSocks can be stored with the same type: PartialKeyPath<DrawContents> . The Value parameter has been type-erased.

KeyPaths of reference types

This shouldn’t be a too big surprise, but if you use a keypath on a reference type (for example a class )

Are keypaths new?

Keypaths have been around for some time, they’re present in Objective-C ! However, they were not type safe ( keyPath() is actually a String ).

#keyPath(Person.firstname)

Limitations

Key path cannot refer to static member 'lifeform'

If we change Person to have a static var.

As, well, keypaths cannot refer to static members! What a shame!

Opportunity

Want to use KVO in your code? You’re going to need to call a keypath when you use func observe<Value>(_ keyPath: KeyPath<ViewController, Value>, options: NSKeyValueObservingOptions = [], changeHandler: @escaping (ViewController, NSKeyValueObservedChange<Value>) -> Void) -> NSKeyValueObservation , and a sample implementation might look something like the following:

So consider yourself TOLD!

Conclusion

So, keypaths are actually useful in iOS development, being relevant for Combine and SwiftUI as well as KVO .

Do you want to buckle up and become familiar with this, or not? I'd say understanding what you need to do is important- and you can read up Combine and UIKit on this HERE.

I hope that this article has helped you out in become more familar in this relatively new feature of Swift.

If you’ve any questions, comments or suggestions please hit me up on Twitter