1
   @objc(EventNotificationInfo)
    class EventNotificationInfo: NSObject, NSSecureCoding {
        public var name: String
        public var startTime: Date
        public var hexColor: String

         init(name: String, startTime: Date, hexColor: String) {
            self.name = name
            self.startTime = startTime
            self.hexColor = hexColor
        }

        private  struct Keys {
            static var name: String = "name"
            static let startTime: String = "startTime"
            static let hexColor: String = "hexColor"
        }

        static var supportsSecureCoding: Bool = true

        func encode(with coder: NSCoder) {
            coder.encode(name, forKey: Keys.name)
            coder.encode(startTime, forKey: Keys.startTime)
            coder.encode(hexColor, forKey: Keys.hexColor)
        }

        required init?(coder: NSCoder) {
            guard let name = coder.decodeObject(forKey: Keys.name) as? String  else {
                return nil
            }

            guard let startTime = coder.decodeObject(forKey: Keys.startTime) as? Date else {
                print("You are here")
                return nil
            }

            guard let color = coder.decodeObject(forKey: Keys.hexColor) as? String  else {
                return nil
            }
            self.name = name
            self.startTime = startTime
            self.hexColor = color
        }
    }

An instance of the EventNotificationInfo object.

let event = EventNotificationInfo(name: "Hello from California",
                                        startTime:Date(),
                                        hexColor: "000000")

Using the following code, I archive and unarchive the above object.

let eventInfo  = try? NSKeyedArchiver.archivedData(withRootObject: event, requiringSecureCoding: false)


let unArchive = try! NSKeyedUnarchiver.unarchivedObject(ofClass: TPEventNotificationInfo.self, from: eventInfo!)

A Fatal error occurs when the xCode reaches a breakpoint that i set on the last line (unArchive variable). This is the console's message.

You are here.
Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'startTime' was of unexpected class 'NSDate'. Allowed classes are '{(
    EventNotificationInfo
)}'." UserInfo={NSDebugDescription=value for key 'startTime' was of unexpected class 'NSDate'. Allowed classes are '{(
    EventNotificationInfo
)}'.}: file

What could be the problem? How to unarchive this object?


Info: I have used startTime of type String. And it went well.

mahan
  • 12,366
  • 5
  • 48
  • 83

1 Answers1

2

Per the documentation for NSSecureCoding:

An object that does override init(coder:) must decode any enclosed objects using the decodeObjectOfClass:forKey: method. For example:

let obj = decoder.decodeObject(of:MyClass.self, forKey: "myKey")

You should do this in your implementation of init(coder:).

guard let startTime = coder.decodeObject(of: NSDate.self, forKey: Keys.startTime) as Date? else {
    return nil
} 

In addition, instead of using try!, you should wrap this in a do/catch so that you would see if an errors occurs.

Rudedog
  • 4,323
  • 1
  • 23
  • 34