如何在Swift 3中将自定义类保存为CoreData实体的属性?

时间:2017-07-20 09:45:48

标签: swift core-data

我有一个CoreData实体SavedWorkout。它具有以下属性: enter image description here

completionCounter是一个Bool数组,workout是一个名为Workout的自定义类。

我正在保存我的数据:

let saveCompletionCounter = currentCompletionCounter
let saveDate = Date() as NSDate
let saveRoutineIndex = Int16(currentWorkoutRoutine)
let saveWorkout = NSKeyedArchiver.archivedData(withRootObject: workout)

item.setValue(saveDate, forKey: "date")
item.setValue(saveWorkout, forKey: "workout")
item.setValue(saveRoutineIndex, forKey: "routineIndex")
item.setValue(saveCompletionCounter, forKey: "completionCounter")

do {
  try moc.save()
  print("save successful")
} catch {
  print("saving error")
}

其中mocNSManagedObjectContext的实例,itemNSManagedObject的实例:

moc = appDelegate.managedObjectContext
entity = NSEntityDescription.entity(forEntityName: "SavedWorkout", in: moc)!
item = NSManagedObject(entity: entity, insertInto: moc)

根据thisthis这一点,我已将Workout课程符合NSObjectNSCoding,所以现在看起来像这样:

class Workout: NSObject, NSCoding {

  let name: String
  let imageName: String
  let routine: [WorkoutRoutine]
  let shortDescription: String

  required init?(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    imageName = aDecoder.decodeObject(forKey: "imageName") as! String
    routine = aDecoder.decodeObject(forKey: "routine") as! [WorkoutRoutine]
    shortDescription = aDecoder.decodeObject(forKey: "shortDescription") as! String
  }

  func encode(with aCoder: NSCoder) {
    aCoder.encode(name, forKey: "name")
    aCoder.encode(imageName, forKey: "imageName")
    aCoder.encode(routine, forKey: "routine")
    aCoder.encode(shortDescription, forKey: "shortDescription")
  }

  init(name: String, imageName: String, routine: [WorkoutRoutine], shortDescription: String) {
    self.name = name
    self.imageName = imageName
    self.routine = routine
    self.shortDescription = shortDescription
  }
}

但是我总是在routine: aDecoder.decodeObject...行上收到错误。

错误说:

NSForwarding: warning: object 0x60800002cbe0 of class 'App.WorkoutRoutine' does not implement methodSignatureForSelector: -- trouble ahead

Unrecognized selector -[FitLift.WorkoutRoutine replacementObjectForKeyedArchiver:]

为什么这会给我一个错误,而不是另一个Transformable属性?如何将自定义类保存为CoreData实体的属性?

1 个答案:

答案 0 :(得分:3)

问题是,WorkoutRoutine本身就是一个自定义类,而且由于您的错误,它不符合NSCoding,因此aCoder.encode(routine, forKey: "routine")并不真正知道如何对其进行编码,以及{ {1}}不知道如何解码它。

没有真正相关,但请为您的编码器和编码器初始化程序尝试更安全的方法,因为如果编码器不包含您要查找的键(因任何原因),强制解包可能会导致崩溃

routine = aDecoder.decodeObject(forKey: "routine") as! [WorkoutRoutine]