具有用于比较日期的瞬态属性的 FetchedResultsController
FetchedResultsController with transient attribute for comparing dates
我在 CoreData 中有一个 JOURNEY 实体。它具有 arrivalDate 和 departmentDate 作为属性。
arrivalDate 和 departureDate 都是 NSDate 类型?
我只想获取持续时间超过一个小时的旅程。
为了实现这一点,我在 Journey+CoreDataClass 中创建了一个瞬态属性
public var isJourneyLongEnough: Bool{
if let arrival = arrivalDate as Date?, let departure = departureDate as Date?{
let duration = departure.timeIntervalSince(arrival)
return duration >= 3600 ? true : false
} else{
return false
}
}
当我尝试获取它时崩溃并出现错误:*** 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'keypath isJourneyLongEnough not found in entity.
在对这个问题进行更多研究后,我发现我们不能在谓词中使用瞬态 属性,因为从 persistentStore 获取托管对象时这些不存在。
You cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself). ... To summarize, though, if you execute a fetch directly, you should typically not add Objective-C-based predicates or sort descriptors to the fetch request. Instead you should apply these to the results of the fetch.
实现此目标的最佳方法是什么?我正在使用 FetchedResultsController 在 UITableView
中显示所有旅程
您可以试试下面的 NSPredicate,它基于 another question,本质上是将日期转换为 NSNumber,减去它们,然后比较结果是大于还是小于 3600 秒。
我没试过,但也许有帮助。最初的问题是在 ObjC 中,所以也许有些事情发生了变化。
NSPredicate(format: “departureDate != nil AND arrivalDate != nil AND CAST(departureDate, ‘NSNumber‘) - CAST(arrivalDate, ‘NSNumber‘) >= 3600“)
时间戳以秒为单位存储(自参考日期 2001 年 1 月 1 日起)
在 Core Data SQLite 文件中,可以简单地检查两者之间的区别
出发和到达日期至少为 3600 秒:
let predicate = NSPredicate(format: "arrivalDate - departureDate >= 3600")
fetchRequest.predicate = predicate
这在我的测试中按预期工作。如果最短行程时间
在运行时确定,使用
let minDuration = 3600
let predicate = NSPredicate(format: "arrivalDate - departureDate >= %@", minDuration as NSNumber)
备注:以上谓词仅在核心数据中使用时才有效
获取请求。以下变体适用于核心数据
获取请求并使用直接评估的谓词:
NSPredicate(format: "arrivalDate.timeIntervalSinceReferenceDate - departureDate.timeIntervalSinceReferenceDate >= 3600")
我在 CoreData 中有一个 JOURNEY 实体。它具有 arrivalDate 和 departmentDate 作为属性。
arrivalDate 和 departureDate 都是 NSDate 类型?
我只想获取持续时间超过一个小时的旅程。
为了实现这一点,我在 Journey+CoreDataClass 中创建了一个瞬态属性
public var isJourneyLongEnough: Bool{
if let arrival = arrivalDate as Date?, let departure = departureDate as Date?{
let duration = departure.timeIntervalSince(arrival)
return duration >= 3600 ? true : false
} else{
return false
}
}
当我尝试获取它时崩溃并出现错误:*** 由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'keypath isJourneyLongEnough not found in entity.
在对这个问题进行更多研究后,我发现我们不能在谓词中使用瞬态 属性,因为从 persistentStore 获取托管对象时这些不存在。
You cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself). ... To summarize, though, if you execute a fetch directly, you should typically not add Objective-C-based predicates or sort descriptors to the fetch request. Instead you should apply these to the results of the fetch.
实现此目标的最佳方法是什么?我正在使用 FetchedResultsController 在 UITableView
中显示所有旅程您可以试试下面的 NSPredicate,它基于 another question,本质上是将日期转换为 NSNumber,减去它们,然后比较结果是大于还是小于 3600 秒。
我没试过,但也许有帮助。最初的问题是在 ObjC 中,所以也许有些事情发生了变化。
NSPredicate(format: “departureDate != nil AND arrivalDate != nil AND CAST(departureDate, ‘NSNumber‘) - CAST(arrivalDate, ‘NSNumber‘) >= 3600“)
时间戳以秒为单位存储(自参考日期 2001 年 1 月 1 日起) 在 Core Data SQLite 文件中,可以简单地检查两者之间的区别 出发和到达日期至少为 3600 秒:
let predicate = NSPredicate(format: "arrivalDate - departureDate >= 3600")
fetchRequest.predicate = predicate
这在我的测试中按预期工作。如果最短行程时间 在运行时确定,使用
let minDuration = 3600
let predicate = NSPredicate(format: "arrivalDate - departureDate >= %@", minDuration as NSNumber)
备注:以上谓词仅在核心数据中使用时才有效 获取请求。以下变体适用于核心数据 获取请求并使用直接评估的谓词:
NSPredicate(format: "arrivalDate.timeIntervalSinceReferenceDate - departureDate.timeIntervalSinceReferenceDate >= 3600")