Ios 带有NSSortDescriptor和;CoreData驱动的应用程序w iCloud中的NSFetchedResultsController

Ios 带有NSSortDescriptor和;CoreData驱动的应用程序w iCloud中的NSFetchedResultsController,ios,objective-c,swift,core-data,nsfetchedresultscontroller,Ios,Objective C,Swift,Core Data,Nsfetchedresultscontroller,我在应用程序中使用iCloud sync的核心数据实现自定义分区时遇到问题 我制作了一个示例应用程序来说明我的问题:它在CoreData中有一个事件列表(使用FRC获取) 事件属性: @objc(Event) class Event: NSManagedObject { @NSManaged var timeStamp: NSDate? @NSManaged var name: String? @NSManaged var sectionIdentifier :Int32 } 我已经根据项

我在应用程序中使用iCloud sync的核心数据实现自定义分区时遇到问题

我制作了一个示例应用程序来说明我的问题:它在CoreData中有一个事件列表(使用FRC获取)

事件属性:

@objc(Event)
class Event: NSManagedObject {

@NSManaged var timeStamp: NSDate?
@NSManaged var name: String?
@NSManaged var sectionIdentifier :Int32

}
我已经根据项目的时间戳实现了自定义部分:

  • 过去
  • 今天
  • 明天
  • 未来7天
  • 未来
  • 没有日期

    enum SectionType:Int32{
    case inPast = 9
    case Today = 10
    case Tomorrow
    case Next7Days
    case InFuture
    case NotSet = 14
    
    func title()->String{
        switch self {
        case .inPast:
            return "In Past"
        case .Today:
            return "Today"
        case .Tomorrow:
            return "Tomorrow"
        case .Next7Days:
            return "Next 7 Days"
        case .InFuture:
            return "In Future"
        default:
            return "No due date"
        }
    }
    
    }

财务汇报局守则

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

    let fetchRequest = NSFetchRequest()
    let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext!)
    fetchRequest.entity = entity
    fetchRequest.fetchBatchSize = 20

    let sortDescriptors = [
        NSSortDescriptor(key: "sectionIdentifier", ascending: true),
        NSSortDescriptor(key: "timeStamp", ascending: true)
    ]

    fetchRequest.sortDescriptors = sortDescriptors

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
        managedObjectContext: self.managedObjectContext!,
        sectionNameKeyPath: "sectionIdentifier",
        cacheName:nil)

    aFetchedResultsController.delegate = self

    _fetchedResultsController = aFetchedResultsController

    var error: NSError? = nil
    if !_fetchedResultsController!.performFetch(&error) {
         abort()
    }

    return _fetchedResultsController!
}    
一切似乎都在运行,事件按sectionIdentifier分组。 但如果它现在与其他时区的设备同步,则由于时间差异,事件将被错误分组

使用transient属性会有所帮助,但我不能使用NSSortDescriptor对节进行排序

有什么解决办法吗?我真的不想在每个节中填充数组等等


好心

所以我通过实现一个transient属性解决了我的问题

唯一剩下的问题是没有日期的事件被放在列表的顶部。 但我通过添加另一个属性hasDate(Bool)和第二个NSSortDescriptor解决了这个问题

ManagedObject:

import Foundation
import CoreData

enum SectionType:String{
    case inPast = "10"
    case Today = "11"
    case Tomorrow = "12"
    case Next7Days = "13"
    case InFuture = "14"
    case NotSet = "15"

func title()->String{
    switch self {
    case .inPast:
        return "In Past"
    case .Today:
        return "Today"
    case .Tomorrow:
        return "Tomorrow"
    case .Next7Days:
        return "Next 7 Days"
    case .InFuture:
        return "In Future"
    default:
        return "No due date"
    }
}
}



@objc(Event)

class Event: NSManagedObject {

@NSManaged var timeStamp: NSDate?
@NSManaged var noDate: Bool
@NSManaged var name: String?

var sectionIdentifier :String? {
    get {
        var str : String

            if let aDate = self.timeStamp {
                if aDate.isToday() || aDate.isYesterday() {
                   str = SectionType.Today.rawValue
                } else if aDate.isTommorow() {
                     str = SectionType.Tomorrow.rawValue
                } else if aDate.isNext7Days() {
                     str = SectionType.Next7Days.rawValue
                } else if aDate.inPast(){
                     str = SectionType.inPast.rawValue
                } else {
                     str = SectionType.InFuture.rawValue
                }

            }else {
                 str = SectionType.NotSet.rawValue
            }

        return str
    }
    set {
        self.sectionIdentifier = newValue
    }
}



func setTime(date : NSDate?){
    self.willChangeValueForKey("timeStamp")
    self.setValue(date, forKey: "timeStamp")
    self.didChangeValueForKey("timeStamp")

    if let date = date {
        self.noDate = false
    }
}

class func keyPathsForValuesAffectingSectionIdentifier() -> NSSet {
    return  NSSet(object: "timeStamp")
}
}

财务汇报局:

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

        let fetchRequest = NSFetchRequest()
        let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext!)
        fetchRequest.entity = entity
        fetchRequest.fetchBatchSize = 20

        let sortDescriptors = [
//            NSSortDescriptor(key: "sectionIdentifier", ascending: true),
            NSSortDescriptor(key: "noDate", ascending: true),
            NSSortDescriptor(key: "timeStamp", ascending: true)
        ]

        fetchRequest.sortDescriptors = sortDescriptors

        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
            managedObjectContext: self.managedObjectContext!,
            sectionNameKeyPath: "sectionIdentifier",
            cacheName:nil)

        aFetchedResultsController.delegate = self

        _fetchedResultsController = aFetchedResultsController

        var error: NSError? = nil
        if !_fetchedResultsController!.performFetch(&error) {
             abort()
        }

        return _fetchedResultsController!
    }  

在按时间获取核心数据对象时,应该使用瞬态属性,因为这样该节就可以动态更新,因为时间在不断变化,所以很难继续重置存储的属性,感谢回复!我已经用transient解决了我的问题。我第一次没有正确使用它们。苹果公司的项目起到了作用。最好不要有零时间戳。NSDate.distantFuture()应为默认值。