简体   繁体   中英

Swift NSSecureCoding unexpectedly found nil while unwrapping

I am storing a transformable in CoreData and am trying to make it NSSecureCoding compliant, but I keep getting Unexpectedly found nil whilst unwrapping an optional value, when I try to decode

in the XCDataModel, I am set the property as transformable and use the custom class AssignedExerciseObjects, I have also set the transformer to AssignedExerciseObjectsValueTransformer

I have also registered the transformer in my CoreData stack

here is a copy of my transformer

@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)
}
}

and here is a copy of my custom class

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))
    
    }
}

this is where it gives me the error

let mAssignedExerciseObjects = aDecoder.decodeObject(of: NSArray.self, forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]

I'm still fairly new to swift, but I cannot for the life of me work out why it is returning a nil value?

when the record is created, it all seems to work fine, but when I try to display the record in a table, I get the error

any help is greatly appreciated

regards

Jamie

OK, I've fixed it

Adding my custom class fixed the issue

 let mAssignedExerciseObjects = aDecoder.decodeObject(of: [AssignedExerciseObject.self, NSArray.self], forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]
   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM