Getting string from Swift 4 new key path syntax? Getting string from Swift 4 new key path syntax? ios ios

Getting string from Swift 4 new key path syntax?


A bit late to the party, but I've stumbled upon a way of getting a key path string from NSObject subclasses at least:

NSExpression(forKeyPath: \UIView.bounds).keyPath


Short answer: you can't. The KeyPath abstraction is designed to encapsulate a potentially nested property key path from a given root type. As such, exporting a single String value might not make sense in the general case.

For instance, should the hypothetically exported string be interpreted as a property of the root type or a member of one of its nested types? At the very least a string array would need to be exported to address such scenarios...

Per type workaround. Having said that, given that KeyPath conforms to the Equatable protocol, you can provide a custom, per type solution yourself. For instance:

struct Auth {    var email: String    var password: String}struct User {    var name: String    var auth: Auth}

provide an extension for User-based key paths:

extension PartialKeyPath where Root == User {    var stringValue: String {        switch self {        case \User.name: return "name"        case \User.auth: return "auth"        case \User.auth.email: return "auth.email"        case \User.auth.password: return "auth.password"        default: fatalError("Unexpected key path")    }}

usage:

let name:  KeyPath<User, String> = \User.namelet email: KeyPath<User, String> = \User.auth.emailprint(name.stringValue)  /* name */print(email.stringValue) /* auth.email */

I wouldn't really recommend this solution for production code, given the somewhat high maintenance, etc. But since you were curious this, at least, gives you a way forward ;)


For Objective-C properties on Objective-C classes, you can use the _kvcKeyPathString property to get it.

However, Swift key paths may not have String equivalents. It is a stated objective of Swift key paths that they do not require field names to be included in the executable. It's possible that a key path could be represented as a sequence of offsets of fields to get, or closures to call on an object.

Of course, this directly conflicts with your own objective of avoiding to declare properties @objc. I believe that there is no built-in facility to do what you want to do.