ios - 无法解码 Swift 中保存的信息

标签 ios swift nskeyedarchiver nskeyedunarchiver

我试图在 swift 中使用 NSKeyedArchiver 保存一个非常简单的对象,我看到它保存正确,有值,但是每当它尝试解码保存的数据时它都会失败。我是 swift 的新手,我尝试过谷歌搜索和 os_log (ing) 一切,但我看不出问题出在哪里。这是我要保存的对象...

class TrackedAmount: NSObject, NSCoding {
  var cups: Int
  var fraction: Float?

  struct PropertyKey {
    static let cups = "cups"
    static let fraction = "fraction"
  }
  init?(cups: Int, fraction: Float?) {
    os_log("Running init? function", log: .default, type: .debug)
    if(cups < 0) {
      os_log("Cups less than 0. Returning nil", log: .default, type: .debug)
      return nil
    }
    self.cups = cups
    self.fraction = fraction
  }

  required convenience init? coder aDecoder: NSCoder) {
    os_log("Running required convenience init? function", log: .default, type: .debug)
    guard let cups = aDecoder.decodeObject(forKey: PropertyKey.cups) as? Int else {
      os_log("Unable to decode cups", log: .default, type: .debug)
      return nil
    }
    guard let fraction = aDecoder.decodeObject(forKey: PropertyKey.fraction) as? Float else {
      os_log("Unable to decode fraction", log: .default, type: .debug)
      return nil
    }
    self.init(cups: cups, fraction: fraction)
  }

  func encode(with aCoder: NSCoder) {
    aCoder.encode(cups, forKey: PropertyKey.cups)
    aCoder.encode(fraction, forKey: PropertyKey.fraction)
  }

然后在我的 ViewController 中,我试图像这样获取并保存它们,...

 private func saveAmount() {
    trackedToday = TrackedAmount(cups: selectedCups, fraction: selectedFraction)
    print("data.... cups: " + String(trackedToday!.cups) + " fractions: " + String(trackedToday!.fraction!))
    let fullPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("dailytracked")
    do {
      let data = try NSKeyedArchiver.archivedData(withRootObject: trackedToday!, requiringSecureCoding: false)
      try data.write(to: fullPath)
    } catch {
      os_log("Unable to save tracking amount", log: .default, type: .debug)
    }
  }

  private func loadDailyTracked() -> TrackedAmount? {
    let fullPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("dailytracked")
    if let nsData = NSData(contentsOf: fullPath) {
      do {
        let data = Data(referencing: nsData)
        if let loadedData = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? TrackedAmount {
          os_log("it finally worked", log: .default, type: .debug)
          return loadedData
        }
      } catch {
        os_log("Couldn't read from file", log: .default, type: .debug)
        return nil
      }
    return nil
  }

保存正确,但每当我尝试运行 loadDailyTracked() 方法时,我都会在 xcode 的输出部分得到以下内容...

Running required convenience init? function

Unable to decode cups

我似乎无法弄清楚为什么它不能解码杯子,我知道数据正在保存,因为没有任何日志显示任何失败,除非它试图从保存的数据中读取。我什至在保存之前记录了信息,它显示了正确的数据。有人有主意吗?我真的是 IOS 和 Swift 的新手,我就是想不通。谢谢。

*旁注,如果您需要更多代码或信息,我很乐意提供,我只是想在不必要的情况下避免帖子太大。

最佳答案

NSCoder 而言,IntFloat 等标量类型不是 对象,专用方法也不是t 返回可选值

required convenience init? coder aDecoder: NSCoder) {
    os_log("Running required convenience init? function", log: .default, type: .debug)
    let cups = aDecoder.decodeInteger(forKey: PropertyKey.cups)
    let fraction = aDecoder.decodeFloat(forKey: PropertyKey.fraction)
    self.init(cups: cups, fraction: fraction)
}
Swift 中的

NSCoding 非常繁重。强烈建议使用 Codable 协议(protocol)来序列化结构和类。

关于ios - 无法解码 Swift 中保存的信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54873802/

相关文章:

带有 NSCoding 的 iOS 归档对象失败

ios - 如果模型对象文件有很多依赖项,如何将其导入到我的 watch 扩展中

swift - NSKeyedUnarchiver 无法解码我的一些 key

ios - 我应该为远程应用程序使用哪种观察者模式?

ios - React-Native:关闭/退出 React-Native View 回到 Native

ios - 除了 MVC,iOS 还使用了哪些设计模式?

ios - 处理包含 UIButton 的 UIView 的触摸事件

ios - 在 ARKit 上使用 YoutubePlayerView

ios - 如何从 CoreData 获取实时值或者知道 iOS Swift 中的值是否与上次获取的值发生变化?

ios - 将字符串添加到另一个字符串的开头