Have you ever listen the keypath
keyword? - No
If you have used SwiftUI you may be familiar with
List
usingidentifiers
just like this...List(data, id: \.id) { ... }
on this code\.id
is thekeypath
.
In short words keypaths
are store references to your properties
What amazing thing huh?! 😁
Much easier to explain this using our handy dandy?... (📣 notebook!) - sorry, no!, example! (Bad joke from Blue's clues in case you didn't get it).
Let's use this simple classes to work with.
class BasicInfo {
let name: String
var quickSlots: (up: String?, left: String?, right: String?, down: String?)
init(name: String, quickSlots: (up: String?, left: String?, right: String?, down: String?)) {
self.name = name
self.quickSlots = quickSlots
}
}
class Jill {
var basicInfo: BasicInfo
var isInfected = false
init(name: String) {
self.basicInfo = BasicInfo(name: name, quickSlots: (up: "G19 Handgun", left: nil, right: "Survival Knife", down: nil))
}
}
So in here we just have a simple class
that have some basic info, later a Jill
(Resident Evil character) class that depends from BasicInfo
.
We are not going to dive deep on this class because it is not what we are talking about.
To get access to properties we can use dot-notation.
let jill = Jill(name: "Jill Valentine")
jill.isInfected // <= false
We can just get the same result using keypaths
// 1
let isInfected = \Jill.isInfected
// 2
let isJillInfected = jill[keypath: isInfected]
We just need a backslash then the path to reference, our class and the property we want to reference, look that I am using the class itself and not the instance.
Using keypath's subscript we can get the value of the property that we are referencing to.
But... our property doesn't need to be directly on our class
, it can be from several levels deep
Take a look at this.
let characterName = \Jill.basicInfo.name
let jillName = jill[keyPath: characterName]
As you can see we are now trying to access the name
from the basicInfo
property, and the access, it is just the same way.
Additional to deep levels, guess what? - We can use it with tuples.
A
tuple
is just a set of variables composed in one.
let upSlot = \Jill.basicInfo.quickSlots.up
let jillUpSlot = jill[keyPath: upSlot]
And there you go, the same result we were expecting!
Also, we don't need to create the full path at first, we can have a base keypath
and just append another to it.
// 1
let basicInfoPath = \Jill.basicInfo
// 2
let rightSlotPath = basicInfoPath.appending(path: \.quickSlots.right)
// 3
let jillRightSlot = jill[keyPath: rightSlotPath]
- We have our base
keypath
that references thebasicInfo
property - We ju.st append the new route using the root (
\
) and moving deeper, in this case ourright
property inside ourtuple
. - We use our
keypath
such as before.
Until know we have been using this feature to read values, but... we can set
values to it!.
// 1
let leftSlotPath = \Jill.basicInfo.quickSlots.left
// 2
jill[keyPath: leftSlotPath] = "M3 Shotgun"
- We create the reference to our property, such as before.
- Let's suppose we got a new gun and it automatically is assigned to our left side, and this is as simple as just assign it.
There is one more feature we can take approach of... Dynamic Member Lookup.
I have a post related to this topic using subscripts
, it is a 3 minutes approximately lecture.
Subscripts: Dynamic Member Lookup
Juan Dorado ・ Aug 8 '20 ・ 3 min read
In short words, using Dynamic Member Lookup we can make Swift a dynamic language related to Phyton or PHP.
@dynamicMemberLookup
class Carlos {
var basicInfo: BasicInfo
init(name: String) {
self.basicInfo = BasicInfo(name: name, quickSlots: (up: "Assault Rifle", left: "G18 Handgun", right: "Survival Knife", down: nil))
}
subscript(dynamicMember keyPath: KeyPath<BasicInfo, String>) -> String {
return basicInfo[keyPath: keyPath]
}
}
I recommend you to take a look to the previous post about Dynamic Member Lookup, where I explain a little bit more how this works.
let carlos = Carlos(name: "Carlos Oliveira")
carlos.name
Finally we just need to access to the dynamic property we want to, we doesn't need to create our keypath
.
And with this you got some more knowledge and learn a new skill to add it to your list!.
Happy coding 👨💻!
Top comments (0)