我在使用NSKeyedArchiver编码和解码自定义Swift类的Date类型属性时遇到了困难。我用KeyedArchiver打电话给:
let savedData = NSKeyedArchiver.archivedData(withRootObject: timers)
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "timers")
这是我的班级声明的上半部分:
class TimerModel: NSObject, NSCoding, AVAudioPlayerDelegate {
var name: String
var active: Bool
var paused: Bool
var duration: Int
var remainingWhenPaused: Int?
var timerEndTime: Date?
var timerStartTime: Date?
var audioAlert: AlertNoise
var UUID: String
var colorScheme: BaseColor
var alarmRepetitions: Int
var timerRepetitions: Int
var currentTimerRepetition: Int
var audioPlaying: Bool
var player: AVAudioPlayer = AVAudioPlayer()
var countDownTimer: Timer = Timer()
var delegate: timerProtocol? = nil
init(withName name: String, duration: Int, UUID: String, color: BaseColor, alertNoise: AlertNoise, timerRepetitions: Int, alarmRepetitions: Int, timerEndTime: Date? = nil) {
self.name = name
self.active = false
self.paused = false
self.duration = duration
self.UUID = UUID
self.audioAlert = alertNoise
self.colorScheme = color
self.alarmRepetitions = alarmRepetitions
self.audioPlaying = false
self.timerRepetitions = timerRepetitions
self.currentTimerRepetition = 0
super.init()
}
convenience override init() {
self.init(withName: "Tap Timer 1", duration: 10, UUID: Foundation.UUID().uuidString, color: .Red, alertNoise: .ChurchBell, timerRepetitions: 1, alarmRepetitions: 0)
}
// MARK: NSCoding
required convenience init? (coder decoder: NSCoder) {
guard let name = decoder.decodeObject(forKey: "name") as? String
else {
print("init coder name guard failed")
return nil
}
let duration = decoder.decodeInteger(forKey: "duration")
guard let audioAlertRawValue = decoder.decodeObject(forKey: "audioAlert") as? String
else {
print("init coder audioAlert guard failed")
return nil
}
guard let UUID = decoder.decodeObject(forKey: "UUID") as? String
else {
print("init coder UUID guard failed")
return nil
}
guard let colorSchemeRawValue = decoder.decodeObject(forKey: "colorScheme") as? String
else {
print("init coder colorScheme guard failed")
return nil
}
let alarmRepetitions = decoder.decodeInteger(forKey: "alarmRepetitions")
let timerRepetitions = decoder.decodeInteger(forKey: "timerRepetitions")
guard let audioAlert = AlertNoise(rawValue: audioAlertRawValue)
else{
print("No AlertNoise rawValue case found")
return nil
}
guard let colorScheme = BaseColor(rawValue: colorSchemeRawValue)
else{
print("No BaseColor rawValue case found")
return nil
}
var timerEndTimeUnwrapped: Date?
if let timerEndTime = decoder.decodeObject(forKey: "timerEndTime") as? Date {
timerEndTimeUnwrapped = timerEndTime
} else {
timerEndTimeUnwrapped = nil
}
print("initCoder guards passed, initing timer")
print("\(name), \(duration), \(UUID), \(colorScheme), \(audioAlert), \(timerRepetitions), \(alarmRepetitions), \(timerEndTimeUnwrapped)")
self.init(withName: name, duration: duration, UUID: UUID, color: colorScheme, alertNoise: audioAlert, timerRepetitions: timerRepetitions, alarmRepetitions: alarmRepetitions, timerEndTime: timerEndTimeUnwrapped)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(self.name, forKey: "name")
aCoder.encode(self.duration, forKey: "duration")
aCoder.encode(self.audioAlert.rawValue, forKey: "audioAlert")
aCoder.encode(self.UUID, forKey: "UUID")
aCoder.encode(self.colorScheme.rawValue, forKey: "colorScheme")
aCoder.encode(self.alarmRepetitions, forKey: "alarmRepetitions")
aCoder.encode(self.timerRepetitions, forKey: "timerRepetitions")
aCoder.encode(self.timerEndTime, forKey: "timerEndTime")
}
当我尝试从NSUserDefaults取消归档对象时,timerEndTimeUnwrapped
总是以nil
的形式返回。要么我搞砸了解开东西,要么编码或解码都失败了。其他所有东西都按预期返回,只是日期类型有问题
任何帮助都会很棒。
答案 0 :(得分:1)
所以这是一个非常愚蠢的错误,一个类被大量使用后添加属性的问题。我没有在班级的init
函数中设置timerEndTime!