【问题标题】:Swift 3 Date type not encoding as part of custom classSwift 3 Date 类型不编码为自定义类的一部分
【发布时间】:2016-09-22 11:04:47
【问题描述】:

我在使用 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。要么我搞砸了拆包,要么编码或解码失败。其他一切都按预期返回,只是日期类型有问题

任何帮助都会很棒。

【问题讨论】:

  • 尝试将Date转换为NSDateaCoder.encode(self.timerEndTime as NSDate, forKey: "timerEndTime")
  • 感谢 Nirav D,我发现了这个问题——实际上已经为此奋斗了一天多,我错过了在类的 init 函数中设置 timerEndTime

标签: ios swift nsuserdefaults nscoding nskeyedarchiver


【解决方案1】:

所以这是一个非常愚蠢的错误,一旦一个类被大量使用,添加属性就会出现问题。我没有在课程的init 函数中设置 timerEndTime!

【讨论】:

    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    相关资源
    最近更新 更多