Created
March 15, 2020 12:05
-
-
Save Koze/2ab02e4f249ce00242f2948f186a3fda to your computer and use it in GitHub Desktop.
Type-safe CKRecord with dynamicMemberLookup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension CKRecord { | |
subscript<Root, Value: CKRecordValueProtocol>(dynamicMember keyPath: WritableKeyPath<Root, Value>) -> Value? { | |
get { | |
let key = NSExpression(forKeyPath: keyPath).keyPath | |
return self[key] | |
} | |
set { | |
let key = NSExpression(forKeyPath: keyPath).keyPath | |
// Fatal error: Could not extract a String from KeyPath Swift.ReferenceWritableKeyPath | |
self[key] = newValue | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@objc protocol MyRecord { | |
var aaa: Bool { get set } | |
var bbb: String { get set } | |
} | |
@dynamicMemberLookup | |
protocol MyRecordProtocol { | |
subscript<Value: CKRecordValueProtocol>(dynamicMember keyPath: WritableKeyPath<MyRecord, Value>) -> Value? { get set } | |
} | |
extension CKRecord: MyRecordProtocol { | |
} | |
func usage() { | |
var record = CKRecord(recordType: "Test") as MyRecordProtocol | |
record.aaa = true | |
// Xcode infers type as `Bool?`, but NSExpression occur fatal error. | |
let value = record.aaa | |
print(value) | |
} |
Any ideas on how to fix this crash?
I'm trying to implement a similar utility to access NSDictionary
with NSManagedObject
properties, and getting the same error. Looks like dynamicMemberLookup
provides some different kind of key path, not working with NSExpression
for some reason.
@dtrofimov
This was a bug in Xcode, and has been fixed in Xcode 12.5.
See Xcode 12.5 release notes.
https://developer.apple.com/documentation/xcode-release-notes/xcode-12_5-release-notes
Fixed a crash that occurred when setting a value using a ReferenceWritableKeyPath that was upcast to a WritableKeyPath. (74191390) (FB8999603)
Now you can use the technique of this gist!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This seems good type-safe if it's enable to extract string from keyPath.
See also other ways.
https://gist.github.com/Koze/7fb045148c4772c5c28acb3958192cd9
https://gist.github.com/Koze/f6afb934377717bf34fd285439e86281