-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[SR-5220] Expose API to retrieve string representation of KeyPath #4085
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I need this. I want to extend PMKVObserver to support the new key paths, but it needs to be able to hand a Suggestion: let me type something like |
Suggestion: when the KeyPath refers to an NSObject key path, and when sending the KeyPath as Any to Obj-C, bridge it to NSString. The implementation for transforming the KeyPath to a string already seems to already exists in https://github.com/apple/swift/blob/master/stdlib/public/SDK/Foundation/NSObject.swift, although it's private to the observe implementation. Eridius (JIRA User): In your case, PMKVObserver should be able to use the new Swift 4 NSObject.observe API (see linked file) rather than extracting the key path string. |
@bobergj PMKVObserver cannot use the new NSObject.observe API because all of the logic is implemented on Obj-C, and the new block-based observation API is Swift-only. Also, I'm retaining the older |
@swift-ci create |
Comment by Krunoslav Zaher (JIRA) Hi, I've attached report.swift . Is there some reason why the default `NSObject.observe` API doesn't return `nil` when one of the objects on observation path deallocates? The example I've attached prints: I would expect it to print: |
kzaher (JIRA User) Please don't post unrelated questions in the comments of tickets. Your question has nothing to do with this ticket. |
Comment by Krunoslav Zaher (JIRA) Eridius (JIRA User) I've posted this issue https://bugs.swift.org/browse/SR-6270 and @belkadan marked it as a duplicate of this issue. I would argue my issue is related with this one since I can resolve my issue by either:
I would really want to use `NSObject.observe` API but it seems to me that API is faulty in some cases. I would like some clarification on that behavior, but yeah, I can also post another issue. |
Comment by Alex Lynch (JIRA) The semantics unlocked by this feature request are profound in scope. If swift could provide a type-checked predicate language like the one the OP [posted|https://github.com/kishikawakatsumi/Kuery,] then changes to CoreData object graphs would break predicates that would otherwise fail only at runtime (because the archaic string language isn't compile checked). If the swift core team is concerned about exposing the "string value" of the KeyPath publicly, then perhaps a change to the NSPredicate interpretation process could help. If we could write `NSPredicate(format: "%@ == %@ ", [keyPath, equatableThing])`. The above form would maintain the privacy of the KeyPath's "string value" within the Foundation library. |
Comment by Peter Kamb (JIRA) I heard back from the Swift team via email about this issue: A number of people have raised the NSPredicate interop use case, so maybe Foundation would be interested in providing an overlay for it. That wouldn't require us to make the KVC interop interface public. I'm a bit concerned about providing the KVC string as public API, since people might misinterpret it as usable for Swift reflectiony things, which might be dangerous with ObjC importer renaming and other things. I opened the following radar, which I'd encourage others to duplicate: NSPredicate initialization via Swift KeyPath |
Comment by Alex Lynch (JIRA) Duplicated: NSPredicate initialization via Swift KeyPath |
Comment by Alexey Kravchenko (JIRA) Duplicated: Add Swift KeyPath compatibility with %K in NSPredicate rdar://problem/38862195 |
Comment by Daniel Asher (JIRA) I'd like to duplicate but get: Open RadarCommunity bug reportsSearch ResultsQuery: rdar://problem/38862195No matching results found. |
Comment by Alex Lynch (JIRA) This project is capable of turning KeyPaths into NSPredicates that are compatible with CoreData. |
Comment by Peter Kamb (JIRA) NSExpression can be initialized via a Swift KeyPath, then the keyPath String extracted via NSExpression.keyPath let expresson = NSExpression(forKeyPath: \String.count)
let keyPathString = expresson.keyPath
// Thread 1: Fatal error: Could not extract a String from KeyPath Swift.KeyPath<Swift.String, Swift.Int> This crashes in the same scenarios in which `_kvcKeyPathString` is nil, but is at least a non `_underscoreFunction` alternative in the API. |
Comment by Tom Harrington (JIRA) I could really use this too. In my scenario, I'm working on updates to mogenerator. For convenience in constructing NSPredicates, the generated Core Data code includes per-class structs declared like this: public struct Attributes {
static let capacity = "capacity"
static let name = "name"
static let timestamp = "timestamp"
} Then an NSPredicate can use In recent versions of Swift, it would seem that Swift key paths could take the place of the hard-coded strings above. The predicate would be constructed using something like Although this scenario deals specifically with subclasses of NSManagedObject, using ObjC-style key paths doesn't quite work because the attribute in question might have a non-ObjC type like I'm thinking of this in terms of being able to convert Swift key paths to string representations so that NSPredicate would understand them. For example, given a key path like |
Comment by Stuart Robertson (JIRA) I, too, am working with Realm (in both Swift and ObjC, though Swift primarily) and have run into numerous issues due to refactoring and then having string-based Realm-query strings be incorrect. The ability to use keypaths with Realm (and CoreData) will be greatly appreciated. |
Comment by Frank (JIRA) I also would love to be able to use keypaths in NSPredicates. My current workaround is to use Codable models and access the rawValue of a CodingKey. But this doesn't work where I need to have different CodingKey rawValues (e.g. for JSON decoding)... So +1 for the keyPath way! |
I really wish we could just get a string representation of all key paths instead of just the internal one for KVC-compatible key paths. But I suspect we might not be able to do this given ABI compatibility (since KeyPath operations are inlinable); just giving every key path a KVC-compatible string would presumably cause existing code to start believing that every key path is safe to use with KVC. |
Attachment: Download
Additional Detail from JIRA
md5: dcdfcfcfca5995073623243af75491d3
is duplicated by:
Issue Description:
Expose API to retrieve string representation of KeyPath
We can build a type-safe NSPredicate using KeyPath if we have such an API. We can use `_kvcKeyPathString` currently, but it would be nice if it will be officially visible as a public API.
For example, I created this experimental project using KeyPath and `_kvcKeyPathString`.
Using this extension, you can type-safely write queries that were previously hard-coded with strings as shown below. In addition to type checking, a typo can be prevented, and code completion works.
Before
After
The text was updated successfully, but these errors were encountered: