[英]Swift: Sorting Core Data child entities on fetch based on Date
我正在创建一个日历应用程序,我使用Core Data存储事件。
其组成: DateKey
作为父(与一对多的关系),以CalendarEventModel
。 概念是DateKey
包含yyyy-dd-MM日期字符串,并且当天发生的所有事件都作为子项添加到DateKey
中的CalendarEventModel
作为DateKey。 (我正在使用类定义,没有一个实体是抽象的。)。 CalendarEventModel是包含有关一个日历事件的信息的实体。
我试图完成的任务
一切都按预期工作,除了我无法对取得的结果进行排序。 当我获取与当前日历相关的DateKeys时,我根本无法让它们像这样排序:
我想在CalendarEventModels属性startDate
之后按升序排序每个DateKey中的CalendarEventModel($ 0.startDate <$ 1.startDate)。 然后在具有isAllDay = true
那些之前将CalendarEventModel标记为isAllDay = false
。
问题/问题
calendarEvents
属性的NSOrderedSet,但我还没有找到如何将它用于我的排序标准。 你会如何解决这种排序? 如果需要更多信息,请与我们联系。
我的代码
fileprivate func loadEventsFromCoreData() {
dateFormatter.dateFormat = "yyyy dd MM"
let startDate = Date()
var predicatesForFetch : [NSPredicate] = []
var dateStringArray : [String] = []
var fetchResultsArray : [DateKey]?
for num in 0...9 {
let newDate = startDate.add(TimeChunk(seconds: 0, minutes: 0, hours: 0, days: num, weeks: 0, months: 0, years: 0))
let datePredicate = dateFormatter.string(from: newDate)
dateStringArray.append(datePredicate)
predicatesForFetch.append(NSPredicate(format: "dateInfo == %@", datePredicate))
}
setupSectionArray(eventArray: dateStringArray)
// I'm getting the correct DateKeys and their events.
let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForFetch)
let eventFetch : NSFetchRequest<DateKey> = DateKey.fetchRequest()
eventFetch.predicate = compoundPredicate
// I've tried specifying this sortDescriptor and added it to the eventFetch:
// let descriptor = NSSortDescriptor(key: "calendarEvents", ascending: true) { ($0 as! CalendarEventModel).startDate!.compare(($1 as! CalendarEventModel).startDate!) }
// let sortDescriptors = [descriptor]
// eventFetch.sortDescriptors = sortDescriptors
do {
fetchResultsArray = try coreDataContext.fetch(eventFetch)
} catch {
print("Core Data initial fetch failed in Calendar Controller: \(error)")
}
guard fetchResultsArray != nil else { return }
// Xcode doesn't recognize the .sort() function which does not have a return value... and I don't think its a good idea to use the return function at all since I will have to delete all children and re add the sorted for each fetch.
for eventArray in fetchResultsArray! {
eventArray.calendarEvents?.sorted(by: { ($0 as! CalendarEventModel).startDate!.compare(($1 as! CalendarEventModel).startDate!) == .orderedAscending })
eventArray.calendarEvents?.sorted { ($0 as! CalendarEventModel).isAllDay && !($1 as! CalendarEventModel).isAllDay }
}
events = fetchResultsArray!
}
感谢您阅读我的问题。
一些说明:
"yyyy dd MM"
来排序日期,使用"yyyy MM dd"
或 - 强烈推荐 - Date
类型。 Set
s,它们是无序的。 顺便说一下,将关系声明为本机Set<CalendarEventModel>
而不是未指定的NSSet
,并且是非可选的。 DateKey
记录,使用谓词dateKey.dateInfo >= startDate && dateKey.dateInfo <= endDate
获取CalendarEventModel
记录,并在那里添加两个排序描述符。 获取过滤和排序的记录一次比获取关系项并手动排序更有效。
编辑:
今天午夜到+ 9天使用
let calendar = Calendar.current
let now = Date()
let nowPlus9Days = calendar.date(byAdding: .day, value: 9, to: now)!
let startDate = calendar.startOfDay(for: now)
let endDate = calendar.startOfDay(for: nowPlus9Days)
此代码获取日期范围内的所有已排序CalendarEventModel
,并将数组分组为[Date : [CalendarEventModel]]
字典
let predicate = NSPredicate(format: "dateKey.dateInfo >= %@ && dateKey.dateInfo <= %@", startDate as CVarArg, endDate as CVarArg)
let sortDescriptors = [NSSortDescriptor(key: "startDate", ascending: true), NSSortDescriptor(key: "isAllDay", ascending: true)]
let eventFetch : NSFetchRequest<CalendarEventModel> = CalendarEventModel.fetchRequest()
eventFetch.predicate = predicate
eventFetch.sortDescriptors = sortDescriptors
do {
let fetchResultsArray = try coreDataContext.fetch(eventFetch)
let groupedDictionary = Dictionary(grouping: fetchResultsArray, by: {$0.startDate})
} catch {
print("Core Data initial fetch failed in Calendar Controller: \(error)")
}
在catch
块之后不要执行好的代码。 在获取后将所有好的代码放在do
作用域中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.