我正在制作一个日历应用程序,使用Core Data在其中存储事件。
它由以下各项组成:DateKey
作为CalendarEventModel
的父项(具有一对多关系)。这个概念是DateKey
保留一个yyyy-dd-MM日期字符串,并且当天发生的所有事件都作为子级添加为DateKey
的子集,作为NSOrderedSet中的CalendarEventModel
。 (我正在使用类定义,没有一个实体是抽象的。) CalendarEventModel是包含有关一个日历事件的信息的实体。
我要完成的任务
一切都按预期进行,除了我无法对获取的结果进行排序。当我获取与当前日历相关的DateKeys时,我简直无法让它们像这样进行排序:
我想对CalendarEventModels属性startDate
之后的每个DateKey中的CalendarEventModel进行升序排序($ 0.startDate <$ 1.startDate)。然后,在带有isAllDay = false
的CalendarEventModels之前标记为isAllDay = true
。
问题/问题
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!
}
感谢您阅读我的问题。
答案 0 :(得分:0)
一些注意事项:
"yyyy dd MM"
或-强烈建议使用-"yyyy MM dd"
类型的字符串格式Date
对日期进行排序。 Set
,它们是无序的。顺便说一下,将该关系声明为本机Set<CalendarEventModel>
而不是未指定的NSSet
且为非可选关系。 DateKey
记录,不要获取带有谓词{{1}}的{{1}}记录并在其中添加这两个排序描述符。一次获取经过过滤和排序的记录比获取关系项并手动对其进行排序要有效得多。
编辑:
要获取今天的午夜和+ 9天的使用时间
CalendarEventModel
此代码获取日期范围内所有已排序的dateKey.dateInfo >= startDate && dateKey.dateInfo <= endDate
并将数组分组为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]]
块之后不要执行 good 代码。提取后,将所有 good 代码放在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)")
}
范围内。