使用排序描述符使用两个属性对获取的结果控制器数据进行排序

时间:2017-03-07 20:24:13

标签: swift core-data nsfetchrequest

我有一个简单的植物提醒应用程序。我试图通过Core Data' NSFetchedResultsController对我获得的数据进行排序。我的问题是:我尝试排序的数据依赖于对2个属性的操作。

我有一个Plant对象,其中包含以下属性:waterCyclelastWater

waterCycle是该工厂需要水的天数(Double),lastWater是植物最后一次浇水时的日期(NSDate)。我有一个功能,如果工厂到期,计算自需要水后多少天。 (即3天前需要的水!

经过一些研究,我相信我无法根据计算属性进行排序,也不能使用获取请求做任何过于质朴的事情。我试图通过NSFetchRequestNSSortDescriptor实现这一目标,但似乎没有任何效果。欢迎任何有关如何应对这一挑战的建议。

我想到的一个替代方案是我可以将这些数据保存在对象记录中,但这意味着应用程序需要每天重新计算并保存所有对象,以便只是碰到那个相当晚的数字在我看来很麻烦。

这里有一些代码,请不要犹豫,询问更多信息或代码。谢谢!

NSFetchedResultsController

private var fetchedResultsController: NSFetchedResultsController {
    if _fetchedResultsController != nil {
        return _fetchedResultsController!
    }

    let fetchRequest = NSFetchRequest()
    fetchRequest.entity = NSEntityDescription.entityForName("Plant", inManagedObjectContext: managedObjectContext!)

    // this should sort the list so plant that needs water are on top
    let waterCycleSortDescriptor = NSSortDescriptor(key: "waterCycle", ascending: true)
    let lastWaterSortDescriptor = NSSortDescriptor(key: "lastWater", ascending: true)

    fetchRequest.sortDescriptors = [waterCycleSortDescriptor, lastWaterSortDescriptor]

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
                                                               managedObjectContext: managedObjectContext!,
                                                               sectionNameKeyPath: nil, cacheName: PlantRepository.getCacheName())
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    do {
        try _fetchedResultsController!.performFetch()
    } catch {
        fatalError("\(error)")
    }

    return _fetchedResultsController!
}

我使用与此类似的函数计算了晚期天数(简化为帖子):

static func getLateDays(lastWater: NSDate, waterCycle: Double) -> Int {
    // add waterCycle days to lastWater
    let toDate = lastWater.dateByAddingTimeInterval(NSTimeInterval(60*60*24*waterCycle))
    // calc late days after due date
    let lateDays = NSCalendar.currentCalendar().components(NSCalendarUnit.Day, fromDate: toDate, toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))
    return lateDays.day
}

1 个答案:

答案 0 :(得分:3)

我一直在努力寻找从计算属性/瞬态属性中排序NSFetchedResultsController的方法,并且在尝试几次黑客攻击后发现没有好的选择。

如果我正在解决这个特定的问题,我会添加一个属性来保存植物的目标日期,并将其用于分类。

您不需要每天计算一次,但只有在用户更新lastWater的值时才更新此项 - 这对于确保结果是有序的,并且在视图中是准确的你可以在飞行中计算你前一天(或后面)多少天的浇水时间表。