将 Codable 保存到 UserDefaults 并匹配 NSCoding 的外观

Posted

技术标签:

【中文标题】将 Codable 保存到 UserDefaults 并匹配 NSCoding 的外观【英文标题】:Save a Codable to UserDefaults and matching the look of NSCoding 【发布时间】:2019-07-23 22:10:39 【问题描述】:

我有一个名为Stationstruct,它支持Codable 协议。由于它是一个结构体,它不能支持NSCoding 协议。我想将这些Stations 的数组保存到UserDefaults。我有没有任何问题的代码。

func updateRecentStations(stations: [Station]) 
    let encoder = PropertyListEncoder()
    encoder.outputFormat = .xml
    let data = try! encoder.encode(stationsArray)
    UserDefaults.standard.set(data, forKey: "RecentStations")


func readRecentStations() -> [Station] 
    if let data = UserDefaults.standard.object(forKey: "RecentStations") as? Data 
        let stations: [Station] = try! PropertyListDecoder().decode( [Station].self, from: data)
        return stations
    

这两个都有效。往返没有问题。但是,如果我在 Xcode 中检查 >.plist,或调用 print(Array(UserDefaults.standard.dictionaryRepresentation())),则显示的数据难以辨认。写出来的Data看起来像是以十六进制格式存储的。也就是说,如果我在文本编辑器中打开 >.plist,我可以在其中看到 xml,但 .plist 不应该以这种方式阅读。

UserDefaults 似乎不支持将 plist 写入 .plist。一切正常,但由于 plist 编辑器无法阅读我写的内容,我觉得我做事的方式不正确。

有没有办法支持将Codable 写入UserDefaults,从而在其中以人类可读的方式保持其结构?需要明确的是,我正在寻找一种复制 NSCoding 将添加到 NSUserDefaults 层次结构的方式的方法。

【问题讨论】:

【参考方案1】:

您将Data 存储在UserDefaults 中。这将被编码为 base64 字符串,这就是它不可读的原因。

由于您正在编码为 XML 格式,因此生成的 Data 实际上将是表示 XML 的字符串的数据。所以从data 创建一个String。然后将该字符串存储在UserDefaults 中。然后在查看UserDefaults plist 文件时,XML 将是可读的。

注意:以下内容未经测试。可能有错别字。

func updateRecentStations(stations: [Station]) 
    let encoder = PropertyListEncoder()
    encoder.outputFormat = .xml
    let data = try! encoder.encode(stationsArray)
    let xml = String(data: data, encoding: .utf8)!
    UserDefaults.standard.set(xml, forKey: "RecentStations")


func readRecentStations() -> [Station] 
    if let xml = UserDefaults.standard.object(forKey: "RecentStations") as? String 
        let data = xml.data(using: .utf8)!
        let stations: [Station] = try! PropertyListDecoder().decode( [Station].self, from: data)
        return stations
    

【讨论】:

虽然这通常会解决我最初描述的问题,但这不是我想要的。我已将问题更新为更清晰:我正在寻找一种方法来复制 NSCoding 将添加到 NSUserDefaults 层次结构的方式。 更新您的问题以包含您想要的输出示例。

以上是关于将 Codable 保存到 UserDefaults 并匹配 NSCoding 的外观的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中将 JSON 数据保存到 UserDefault? [复制]

我的 Userdefault 没有保存数据,也没有被 ObjectMapper 快速映射

ios 解决数据请求json解析字典后,由于java某些类库转换json字符串后出现键值为<null>无法保存在userDefault的问题

Swift - 将 [String: Any] 数组保存到 NSUserDefauls

Xcode 中的 UserDefault 不保存文本

IOS中Cocos2d-x UserDefault数据的路径/位置?