Vincent Pradeilles Profile picture
iOS at @photoroom_app 🇫🇷 | Entertainer at @ios_memes | SwiftUI teacher at @mobileworkshop5 | French translator of @NSHipster | @insadelyon alumni

Dec 19, 2022, 15 tweets

KeyPaths are a pretty popular Swift syntax!

But do you think you know all the features of KeyPaths? 🤨

Here are 5 things you (probably) didn't know about KeyPaths 🧵

Let’s start with #1️⃣: Whenever you use a method like `.map { }` or .filter { }`, you can pass it a KeyPath instead of a closure!

And the compiler will take care of automatically translating that KeyPath to a closure 👌

Moving on to #2️⃣: Did you know there’s actually more than one type of KeyPath?

The classic `KeyPath` type is actually a reference to a read-only property.

When we take a `KeyPath` to a writable property, we get a `WritableKeyPath`:

And when working with a reference type, we even get a `ReferenceWritableKeyPath`!

Most of the time, we don’t need to care about these different types, as the compiler will map a literal KeyPath to the correct type.

However, if we write our own APIs then these differences become important, because we’ll need to use the correct type depending on what we want to do with the KeyPath.

(And there are even a few additional types to deal with type erasure!)

Let’s move on to #3️⃣: We are all familiar with KeyPaths that reference properties, but did you know that a KeyPath can also reference a subscript?

Here, for instance, I’m taking a KeyPath to the property `name` of the second element in an array of `Person`.

From there we can simply invoke that KeyPath over the array just like we would do with a single value 👍

Now for #4️⃣, let’s talk about how we can use KeyPaths to write nice little DSLs, like this type-safe predicate syntax.

To make this syntax work in Swift, we actually only need to implement a single function!

We just need to implement an overload of the operator `>`, that takes as its left hand side a KeyPath and as its right hand side a constant, and then use the KeyPath to compare the value of the property to that of the constant!

Finally for #5️⃣: Did you know we can use dynamic member lookup with a KeyPath?

Consider the struct `Order` I’ve just declared: I would like to be able to access the properties of the `address` directly on the struct itself:

To do so, we start by annotating the struct with @dynamicMemberLookup.

Then, we implement a subscript that takes as its argument a KeyPath to a property of an Address and we invoke that KeyPath on the property `address`:

And that’s it, we can now directly access the properties of the `address`!

Since our implementation of the subscript relies on a KeyPath, this syntax is type-safe: meaning that if we try to call a property that doesn’t exist on an `address`, it will result in a compilation error 👌

That's all for this thread 🧵, these were the 5 things you (probably) didn’t know about KeyPaths!

Feel free to share the love and RT the original tweet 🥰

Don't miss my next thread and follow me @v_pradeilles

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling