我在使用带有iCloud同步的核心数据在App中实现自定义部分时遇到问题。
我做了一个示例App来说明我的问题:它有一个CoreData内的事件列表(使用FRC获取)
活动启发:
@objc(Event)
class Event: NSManagedObject {
@NSManaged var timeStamp: NSDate?
@NSManaged var name: String?
@NSManaged var sectionIdentifier :Int32
}
我已经根据项目的timeStamp实现了自定义部分:
没有日期
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"
}
}
}
FRC代码
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对各个部分进行排序。
有什么解决方案吗?我真的不想每个部分填充数组等等。
亲切的问候
答案 0 :(得分:0)
所以我通过实现瞬态属性解决了我的问题。
唯一的问题是没有日期的事件被置于列表顶部。 但我通过添加另一个属性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")
}
}
FRC:
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!
}