#ios #swift #core-data #key #nsmanagedobject
#iOS #swift #core-data #Клавиша #nsmanagedobject
Вопрос:
Есть ли способ получить ключ атрибута объекта Core Data непосредственно из свойства соответствующего NSManagedObject
? Это устранило бы необходимость полагаться на строковый («строго типизированный») код для некоторых ситуаций, тем самым снижая риск ошибки.
Например, я хотел бы заменить следующее:
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdDate", ascending: false)]
… с чем-то более похожим на это:
fetchRequest.sortDescriptors = [NSSortDescriptor(key: exampleNSManagedObject.createdDate.key, ascending: false)]
Я знаю, что .defaultSortDescriptors
это можно использовать для достижения некоторых из этих целей, но только для фиксированного атрибута. Я также знаю, что .entity.attributesByName.keys
это можно использовать для получения списка ключей, но я не установил способ автоматического выделения соответствующего.
Ответ №1:
Является ли строковое выражение #keyPath тем, что вы ищете? Из документов:
Вы используете строковое выражение #keyPath для создания проверенных компилятором ключей и путей к ключам, которые могут использоваться методами KVC
Например:
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(ExampleNSManagedObject.createdDate), ascending: false)]
Комментарии:
1. Именно то, что я искал. В моих основных сортировках и поиске данных больше нет строго типизированного кода. Спасибо!
2. Кстати, я обновил ваш ответ примером, просто чтобы привязать его ближе к исходному вопросу.
Ответ №2:
Ну, конечно, вы могли бы написать расширение NSManagedObject
, содержащее функцию, которая принимала бы написанную человеком строку и возвращала наилучшее совпадение .entity.attributesByName.keys
, и это решило бы проблему, как вы ее изложили.
Но лучший способ — использовать инструмент, который автоматически генерирует такие ключевые константы из вашей модели данных. Ознакомьтесь с mogenerator, профессиональной заменой с открытым исходным кодом для генерации кода Core Data, которая встроена в Xcode. Среди его функций — создание подобного перечисления для каждого объекта:
public enum MyEntityAttributes: String {
case createdDate = "createdDate"
case foo = "foo"
case bar = "bar"
}
и затем к нужной ключевой строке можно получить доступ как MyEntityAttributes.foo
.