我正在使用Xcode 7.3和Swift 2.2和NSFetchedResultsController
。是否可以创建使用谓词和排序描述符配置的所需获取请求来解决此问题?
如果Person
实体具有birthDate
属性,如何配置获取请求以返回即将到来的生日?这是我尝试过的:
我创建了一个名为birthDateThisYear
的瞬态属性,并将其配置为今年返回此人的生日。但我发现你不能在使用Core Data的获取请求中使用transient属性。
我通过使用birthDateDayNumber
和birthDateMonthNumber
属性以及birthDate
的自定义设置器进行非规范化来尝试接受的答案here,但我无法弄清楚谓语。如果今天是12月31日怎么办?不知何故,需要包括Jan,Feb和Mar.
我读过它可以用表达式和比较谓词来完成。但我无法找到解决方案。任何人都有这个工作?
我认为创建一个名为birthDateInYear2000
的非规范化属性是有效的,但同样,它会遇到相同的重叠问题。
有什么想法吗?
答案 0 :(得分:4)
建议:
将生日映射到现在的下一个事件
let calendar = NSCalendar.currentCalendar()
let nextBirthDays = birthdays.map { (date) -> NSDate in
let components = calendar.components([.Day, .Month], fromDate: date)
return calendar.nextDateAfterDate(NSDate(), matchingComponents: components, options: .MatchNextTime)!
}
排序日期
let sortedNextBirthDays = nextBirthDays.sort { $0.compare($1) == .OrderedAscending }
现在sortedNextBirthDays
包含所有即将升级的生日。
在核心数据中,您可以使用birthday和objectID(或全名)获取记录作为字典,创建临时结构,映射和排序项目并获取objectID的人(或使用全名) - 或者您甚至可以将逻辑应用于NSManagedObject
数组
修改强>
如果有关下一个生日的信息存储在持久性商店中(假设它是MySQL商店),则使用NSFetchedResultsController
您可以对表格视图排序进行排序,因为您可以' t应用排序描述符,包括指向瞬态或计算属性的键。
更新nextBirthDate
属性的最佳位置就在创建视图控制器的NSFetchedResultsController
实例之前。
nextBirthDate
Person
创建NSDate
的扩展名,以计算从现在开始的下一次出现日期
extension NSDate {
var nextOccurrence : NSDate {
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Day, .Month], fromDate: self)
return calendar.nextDateAfterDate(NSDate(), matchingComponents: components, options: .MatchNextTime)!
}
}
在闭包中初始化NSFetchResultsController
实例添加代码以更新每条记录的nextBirthDate
属性
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Person")
do {
let people = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [Person]
people.forEach({ (person) in
let nextBirthDate = person.birthDate.nextOccurrence
if person.nextBirthDate == nil || person.nextBirthDate! != nextBirthDate {
person.nextBirthDate = nextBirthDate
}
})
if self.managedObjectContext.hasChanges {
try self.managedObjectContext.save()
}
} catch {
print(error)
}
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptors = [NSSortDescriptor(key:"nextBirthDate", ascending: true)]
fetchRequest.sortDescriptors = sortDescriptors
...
如果视图控制器可以编辑birthDate
属性,请不要忘记更新nextBirthDate
属性以保持视图同步。
答案 1 :(得分:0)
我的建议很相似:
使用如下的闭包:
func fetchBirthdayList(){
// this example considers all birthdays that are like
// |---TODAY---|
// Each hyphen represents a day
let date = Date()
let timeSpan = 3
let cal = Calendar.current
nextBirthDays = self.list.filter { (customer) -> Bool in
if let birthDate = customer.birthDate {
let difference = cal.dateComponents([.day,.year], from: birthDate as! Date, to: date)
return (( (difference.day! <= timeSpan) || ((365 - difference.day!) <= timeSpan) ) && difference.day! >= 0)
}
return false
}
}
如果需要,您可以在之后订购结果。
干杯
奥利弗