I was very happy to find Swift 3's implementation of #keyPath()
, which will eliminate typos and enforce at compile time that the key path actually exists. Much better than manually typing Strings.
https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md
class MyObject {
@objc var myString: String = "default"
}
// Works great
let keyPathString = #keyPath(MyObject.myString)
The Swift docs list the type being passed into #keyPath()
as a "property name".
The property name must be a reference to a property that is available in the Objective-C runtime. At compile time, the key-path expression is replaced by a string literal.
Is it possible to save this "property name" independently, then later pass to #keyPath()
to create a String?
let propertyName = MyObject.myString // error. How do I save?
let string = #keyPath(propertyName)
Is there any support for requiring a property name belonging to a specific Type?
// something like this
let typedPropertyName: MyObject.PropertyName = myString // error
let string = #keyPath(typedPropertyName)
The end goal will be interacting with with APIs that require an NSExpression
for a key path. I would like to write convenience methods that take a valid Property Name as a parameter, rather than random key path strings. Ideally, a Property Name implemented by a specific Type.
func doSomethingForSpecificTypeProperty(_ propertyName: MyObject.PropertyName) {
let keyPathString = #keyPath(propertyName)
let expression = NSExpression(forKeyPath: keyPathString)
// ...
}