Ios 具有用于比较日期的瞬态属性的FetchedResultsController

Ios 具有用于比较日期的瞬态属性的FetchedResultsController,ios,swift,core-data,nsfetchedresultscontroller,Ios,Swift,Core Data,Nsfetchedresultscontroller,我在CoreData中有一个旅行实体。它的属性为arrivalDate和departureDate 到达日期和离开日期都是NSDate类型 我只想带那些持续时间超过一小时的旅行 为了实现这一点,我在我的Travely+CoreDataClass中创建了一个瞬态属性 public var isJourneyLongEnough: Bool{ if let arrival = arrivalDate as Date?, let departure = departureDate as Dat

我在CoreData中有一个旅行实体。它的属性为arrivalDate和departureDate


到达日期和离开日期都是NSDate类型

我只想带那些持续时间超过一小时的旅行

为了实现这一点,我在我的Travely+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 IsJourney足够长。”

在进一步研究这个问题后,我发现我们不能在谓词中使用transient属性,因为从persistentStore获取托管对象时这些属性并不存在

您无法使用基于瞬态属性的谓词进行获取(尽管您可以使用瞬态属性自己在内存中进行筛选)。。。但是,要概括地说,如果直接执行fetch,通常不应该向fetch请求添加基于Objective-C的谓词或排序描述符。相反,您应该将这些应用于获取的结果


实现这一目标的最佳方式是什么?我正在使用FetchedResultsController在UITableView中显示所有行程

您可以尝试以下NSPredicate,它基于日期,本质上将日期强制转换为NSNumber,减去日期,然后比较结果是否大于或小于3600秒

我还没试过,但也许有帮助。最初的问题是在ObjC中,所以可能有些事情改变了

NSPredicate(format: “departureDate != nil AND arrivalDate != nil AND CAST(departureDate, ‘NSNumber‘) - CAST(arrivalDate, ‘NSNumber‘) >= 3600“)

时间戳存储为秒(自参考日期2001年1月1日起) 在核心数据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")

我尝试过你的方法,在获取结果时减去它的工作日期。一天后,当新对象添加到数据库时,应用程序开始崩溃。***由于未捕获异常“NSInvalidArgumentException”而终止应用程序,原因:“数学函数需要NSNumber参数”我需要将其强制转换为NSNumber Iguess@FE_Tech:您是否尝试过其他方法(使用timeIntervalSinceReferenceDate)?是的,使用timeIntervalSinceReferenceDate方法,我的旅程都没有回音。我没有从数据库中获取任何对象。我的TableView是空的。@FE_-Tech:它在我的测试中起作用,但我稍后会再次检查它。否则,我现在没有更好的主意,抱歉。使用TimeIntervalenceReferenceDate正在工作。这个问题对我来说是另一回事。我不知道为什么第一种方法在添加新对象时会导致崩溃。但是这个timeIntervalSinceReferenceDate即使在添加新对象时也能工作。我也尝试过这种方法,但它给了我错误。CoreData:错误:异常处理请求:,不支持的函数表达式CAST(departureDate,“NSNumber”)-CAST(arrivalDate,“NSNumber”),用户信息为(null)arrivalDate和departureDate在旅程实体中是可选的。let predicate=NSPredicate(格式:“arrivalDate!=nil和De出发日期!=nil和(CAST(De出发日期,'NSNumber'))-CAST(arrivalDate,'NSNumber'))>=3600”)这是我在崩溃时遇到的错误***由于未捕获的异常“NSInvalidArgumentException”终止应用程序,原因:“不支持的函数表达式CAST(De出发日期,”,“NSNumber”)-CAST(arrivalDate,“NSNumber”)'可能arrivalDate或departureDate为零?在这种情况下,您可以过滤掉它们,我编辑了我的答案。您也可以在CoreData中设置它们,以便在保存时崩溃,如果它们未设置。