РЕЗЮМЕ
Я хочу иметь возможность создать новое значение на основе выражения в fetchRequest из сущности Core Data.
Наличие объекта с этими атрибутами (короткая версия)
Name Attributes
[Course] -> {licenseStart, name, id}
Я хочу сделать fetchResquest для этого объекта и получить словарь со всеми атрибутами плюс еще одну базу на этом выражении:
licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? "Actually" : "Cooming Soon"
Итак, результат будет:
[ "licenseStart":1,"id":3, "name":"A", "status":0, ...
"licenseStart":2,"id":4, "name":"B", "status":0, ...
"licenseStart":3,"id":6, "name":"B", "status":0, ...
"licenseStart":4,"id":2, "name":"C", "status":0, ...
"licenseStart":5,"id":1, "name":"D", "status":1, ...
"licenseStart":6,"id":7, "name":"E", "status":1, ...
]
POST
Я хочу задать вопрос о проблеме, с которой я столкнулся уже несколько дней назад ... каждый подход, который я пробовал, заканчивается более сложным решением.
Позвольте мне объяснить вам ситуацию:
У меня есть модель CoreData с объектом, который имеет разные атрибуты, один из них - начало лицензии. Это номер временной метки unix, который используется для определения, когда начнется курс.
Итак, когда я хочу заполнить данные для создания UITableView с курсами, я без проблем извлекаю всю эту информацию из базы данных, я использую этот атрибут licenseStart для расчета разделов на основе формулы , это код для UITableView
UITableViewController
let entity = NSEntityDescription.entityForName("Course", inManagedObjectContext: managedObjectContext!)
let req = NSFetchRequest()
let predicate = sectionProtocol?.FRCPredicate
let sort = [NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: true), NSSortDescriptor(key: "courseId", ascending: true)]
req.entity = entity
req.sortDescriptors = sort
req.predicate = predicate
/* NSFetchedResultsController initialization
a 'nil' 'sectionNameKeyPath' generates a single section */
var aFetchedResultsController = NSFetchedResultsController(fetchRequest: req, managedObjectContext: managedObjectContext!, sectionNameKeyPath:"dateStatus", cacheName: nil)
После этого мои результаты (небольшой пример) выглядят так
[ "licenseStart":1,"id":3, "name":"A",...
"licenseStart":2,"id":4, "name":"B",...
"licenseStart":3,"id":6, "name":"B",...
"licenseStart":4,"id":2, "name":"C",...
"licenseStart":5,"id":1, "name":"D",...
"licenseStart":6,"id":7, "name":"E",
]
Что у меня будет в UITableView, будет:
[Actually]
[A]
[B]
[B]
[C]
[Cooming Soon]
[D]
[E]
Итак, сейчас я использую licenseStart для создания двух разделов, как? Легко, просто используя атрибут моей модели под названием dateStatus и создавая два возможных результата с помощью лицензия начинается следующим образом:
ModelClass
var dateStatus : Int {
get {
return licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? "Actually" : "Cooming Soon"
}
}
Итак, снова в моем UITableView я использую методы делегатов dataSource для заполнения строк и разделов.
ПРОБЛЕМА
До сих пор все работает идеально. Но теперь я хочу добавить опцию сортировки, которая позволяет пользователям сортировать результаты по возрастанию или по убыванию, проблема в том, что когда я сортирую, то есть по возрастанию, используя другой вариант сортировки:
let entity = NSEntityDescription.entityForName("Course", inManagedObjectContext: managedObjectContext!)
let req = NSFetchRequest()
let predicate = sectionProtocol?.FRCPredicate
let sort = [NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: false), NSSortDescriptor(key: "courseId", ascending: false)]
req.entity = entity
req.sortDescriptors = sort
req.predicate = predicate
/* NSFetchedResultsController initialization
a 'nil' 'sectionNameKeyPath' generates a single section */
var aFetchedResultsController = NSFetchedResultsController(fetchRequest: req, managedObjectContext: managedObjectContext!, sectionNameKeyPath:"dateStatus", cacheName: nil)
Из-за того, как я создаю разделы на основе licenseStart, результаты этой выборки будут точно такими же, как и раньше:
[ "licenseStart":1,"id":3, "name":"A",...
"licenseStart":2,"id":4, "name":"B",...
"licenseStart":3,"id":6, "name":"B",...
"licenseStart":4,"id":2, "name":"C",...
"licenseStart":5,"id":1, "name":"D",...
"licenseStart":6,"id":7, "name":"E",
]
Что у меня будет в UITableView, будет:
[Actually]
[A]
[B]
[B]
[C]
[Coming Soon]
[D]
[E]
Почему? потому что licenseStart все разные, и он использует этот первый элемент в NSSortDescriptors для извлечения данных ... это не то поведение, которое я хочу, я хочу, чтобы разделы были точно в том же порядке, что и раньше, но элементы внутри расположены по-разному
i.e:
[Actually]
[C]
[B]
[B]
[A]
[Coming Soon]
[E]
[D]
ВОЗМОЖНОЕ РЕШЕНИЕ
Я думал создать новый столбец во время запроса fetchrequest, если я смогу оценить это выражение licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? 0 : 1
в момент извлечения данных, в результате у меня будет этот новый столбец с 0 и 1, как это:
[ "licenseStart":1,"id":3, "name":"A", "status":0, ...
"licenseStart":2,"id":4, "name":"B", "status":0, ...
"licenseStart":3,"id":6, "name":"B", "status":0, ...
"licenseStart":4,"id":2, "name":"C", "status":0, ...
"licenseStart":5,"id":1, "name":"D", "status":1, ...
"licenseStart":6,"id":7, "name":"E", "status":1, ...
]
И теперь я мог использовать этот статус для создания разделов в NSSortDescriptors [NSSortDescriptor(key: "status", ascending: true),NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: true), NSSortDescriptor(key: "courseId", ascending: true)]
по возрастанию и [NSSortDescriptor(key: "status", ascending: true),NSSortDescriptor(key: "licenseStart", ascending: false), NSSortDescriptor(key: "name", ascending: false), NSSortDescriptor(key: "courseId", ascending: false)]
по убыванию.
Это дало бы мне поведение, которое я хочу ... но я не смог придумать красивый и чистый способ сделать это. Я пытался сделать это с помощью NSExpressions, но не могу использовать меньше с выборкой CoreData ..
Кроме того, возможным решением будет создание этого нового столбца в моей модели данных и генерирование этого значения при сохранении данных, но это недопустимый подход, поскольку это значение licenseStart необходимо сравнивать с текущей меткой времени каждый раз, когда пользователь заполняет эту таблицу.
Я спрашиваю, есть ли у кого-нибудь краткое представление или умное решение этой проблемы.
В MySQL или SQLite легко создать новый столбец на основе определенного значения или выражения, но в coredata я новичок, поэтому я не вижу четкого способа сделать это.
Большое спасибо.