How would you feel about wrapping the existing functions on _KVOKeyPathBridgeMachinery:
@nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:AnyKeyPath) -> String @nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:String?) -> AnyKeyPath? In extensions on String and AnyKeyPath respectively to instantiate strings from KeyPaths and KeyPaths from Strings? https://github.com/apple/swift/blob/c5ff1f2cac8da6a14330f4b033b94c7c926d2126/stdlib/public/SDK/Foundation/NSObject.swift#L84 On Fri, Aug 25, 2017 at 11:43 AM Joe Groff <[email protected]> wrote: > > > On Aug 23, 2017, at 11:18 PM, Logan Shire via swift-evolution < > [email protected]> wrote: > > > > Hey folks! > > > > Recently I’ve been working on a small library which leverages the Swift > 4 Codable protocol > > and KeyPaths to provide a Swift-y interface to CoreData. (It maps back > and forth between > > native, immutable Swift structs and NSManagedObjects). In doing so I > found a couple of > > frustrating limitations to the KeyPath API. Firstly, KeyPath does not > provide the name of the > > property on the type it indexes. For example, if I have a struct: > > > > > > struct Person { > > let firstName: String > > let lastName: String > > } > > > > let keyPath = \Person.firstName > > > > > > But once I have a keyPath, I can’t actually figure out what property it > accesses. > > So, I wind up having to make a wrapper: > > > > > > struct Attribute { > > let keyPath: AnyKeyPath > > let propertyName: String > > } > > > > let firstNameAttribute = Attribute(keyPath: \Person.firstName, > propertyName: “firstName”) > > > > > > This forces me to write out the property name myself as a string which > is very error prone. > > All I want is to be able to access: > > > > > > keyPath.propertyName // “firstName” > > > > > > It would also be nice if we provided the full path as a string as well: > > > > > > keyPath.fullPath // “Person.firstName" > > > > > > Also, if I want to get all of the attributes from a given Swift type, my > options are to try to hack > > something together with Mirrors, or forcing the type to declare a > function / computed property > > returning an array of all of its key path / property name pairings. I > would really like to be able to > > retrieve a type-erased array of any type’s key paths with: > > > > > > let person = Person(firstName: “John”, lastName: “Doe”) > > let keyPaths = Person.keyPaths > > let firstNameKeyPath = keyPaths.first { $0.propertyName = “firstName” } > as! KeyPath<Person, String> > > let firstName = person[keypath: firstNameKeyPath] // “John" > > > > > > And finally, without straying too far into Objective-C land, it would be > nice if we could initialize key paths > > with a throwing initializer. > > > > > > let keyPath = try Person.keyPath(“firstName”) // KeyPath<Person, String> > type erased to AnyKeyPath > > let keyPath = AnyKeyPath(“Person.firstName”) > > > > > > Let me know what you think about any / all of these suggestions! > > These would all be great additional features to eventually add to key > paths. I think reflection mechanisms centered on key paths like what you > describe would be a superior replacement for most of what Mirror attempts > to provide. > > -Joe
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
