> 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
