问题描述
我在 CoreData 中存储了一个可转换对象,并试图使其符合 NSSecureCoding,但是当我尝试解码时,在解开可选值的同时意外发现 nil
在 XCDataModel 中,我将属性设置为可转换并使用自定义类 AssignedExerciSEObjects,我还将转换器设置为 AssignedExerciSEObjectsValueTransformer
我也在我的 CoreData 堆栈中注册了变压器
这是我的变压器的副本
@objc(AssignedExerciSEObjectsValueTransformer)
final class AssignedExerciSEObjectsValueTransformer: NSSecureUnarchiveFromDataTransformer {
static let name = NSValueTransformerName(rawValue: String(describing: AssignedExerciSEObjectsValueTransformer.self))
override static var allowedTopLevelClasses: [AnyClass] {
return [NSArray.self,AssignedExerciSEObjects.self]
}
/// Registers the transformer.
public static func register() {
let transformer = AssignedExerciSEObjectsValueTransformer()
ValueTransformer.setValueTransformer(transformer,forName: name)
}
}
这是我的自定义类的副本
import Foundation
public class AssignedExerciSEObjects: NSObject,NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public var assignedExerciSEObjects: [AssignedExerciSEObject] = []
enum Key:String {
case assignedExerciSEObjects = "assignedExerciSEObjects"
}
init(assignedExerciSEObjects: [AssignedExerciSEObject]) {
self.assignedExerciSEObjects = assignedExerciSEObjects
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(assignedExerciSEObjects,forKey: Key.assignedExerciSEObjects.rawValue)
}
public required convenience init?(coder aDecoder: NSCoder) {
let mAssignedExerciSEObjects = aDecoder.decodeObject(of: NSArray.self,forKey: Key.assignedExerciSEObjects.rawValue) as! [AssignedExerciSEObject]
self.init(assignedExerciSEObjects: mAssignedExerciSEObjects)
}
}
public class AssignedExerciSEObject: NSObject,NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public var mainExercise: String = ""
public var prepareTime: String = ""
public var exerciseTime: String = ""
public var highIntensityTime: String = ""
public var restTime: String = ""
public var highLowSplit: Bool = false
public var isCompleted: Bool = false
public var isSkipped: Bool = false
public var order: Double = 0
enum Key:String {
case mainExercise = "mainExercise"
case prepareTime = "prepareTime"
case exerciseTime = "exerciseTime"
case highIntensityTime = "highIntensityTime"
case restTime = "restTime"
case highLowSplit = "highLowSplit"
case isCompleted = "isCompleted"
case isSkipped = "isSkipped"
case order = "order"
}
init(mainExercise: String,prepareTime: String,exerciseTime: String,highIntensityTime: String,restTime: String,highLowSplit: Bool,isCompleted: Bool,isSkipped: Bool,order: Double) {
self.mainExercise = mainExercise
self.prepareTime = prepareTime
self.exerciseTime = exerciseTime
self.highIntensityTime = highIntensityTime
self.restTime = restTime
self.highLowSplit = highLowSplit
self.isCompleted = isCompleted
self.isSkipped = isSkipped
self.order = order
}
public override init() {
super.init()
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(mainExercise,forKey: Key.mainExercise.rawValue)
aCoder.encode(prepareTime,forKey: Key.prepareTime.rawValue)
aCoder.encode(exerciseTime,forKey: Key.exerciseTime.rawValue)
aCoder.encode(highIntensityTime,forKey: Key.highIntensityTime.rawValue)
aCoder.encode(restTime,forKey: Key.restTime.rawValue)
aCoder.encode(highLowSplit,forKey: Key.highLowSplit.rawValue)
aCoder.encode(isCompleted,forKey: Key.isCompleted.rawValue)
aCoder.encode(isSkipped,forKey: Key.isSkipped.rawValue)
aCoder.encode(order,forKey: Key.order.rawValue)
}
public required convenience init?(coder aDecoder: NSCoder) {
let mMainExercise = aDecoder.decodeObject(of: Nsstring.self,forKey: Key.mainExercise.rawValue)! as String
let mPrepareTime = aDecoder.decodeObject(of: Nsstring.self,forKey: Key.prepareTime.rawValue)! as String
let mExerciseTime = aDecoder.decodeObject(of: Nsstring.self,forKey: Key.exerciseTime.rawValue)! as String
let mHighIntensityTime = aDecoder.decodeObject(of: Nsstring.self,forKey: Key.highIntensityTime.rawValue)! as String
let mRestTime = aDecoder.decodeObject(of: Nsstring.self,forKey: Key.restTime.rawValue)! as String
let mHighLowSplit = aDecoder.decodeBool(forKey: Key.highLowSplit.rawValue)
let mIsCompleted = aDecoder.decodeBool(forKey: Key.isCompleted.rawValue)
let mIsSkipped = aDecoder.decodeBool(forKey: Key.isSkipped.rawValue)
let mOrder = aDecoder.decodeDouble(forKey: Key.order.rawValue)
self.init(mainExercise: String(mMainExercise),prepareTime:
String(mPrepareTime),exerciseTime: String(mExerciseTime),highIntensityTime: String(mHighIntensityTime),restTime: String(mRestTime),highLowSplit: Bool(mHighLowSplit),isCompleted: Bool(mIsCompleted),isSkipped: Bool(mIsSkipped),order: Double(mOrder))
}
}
这是它给我错误的地方
let mAssignedExerciSEObjects = aDecoder.decodeObject(of: NSArray.self,forKey: Key.assignedExerciSEObjects.rawValue) as! [AssignedExerciSEObject]
我对 swift 还很陌生,但我终其一生都无法弄清楚为什么它返回 nil 值?
创建记录后,一切似乎都正常,但是当我尝试在表中显示记录时,出现错误
非常感谢任何帮助
问候
杰米
解决方法
好的,我已经修好了
添加我的自定义类解决了问题
let mAssignedExerciseObjects = aDecoder.decodeObject(of: [AssignedExerciseObject.self,NSArray.self],forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]