Swift - 如何将本地存储的对象数组(文件管理器)转换为较新的对象? (带有附加属性)

Posted

技术标签:

【中文标题】Swift - 如何将本地存储的对象数组(文件管理器)转换为较新的对象? (带有附加属性)【英文标题】:Swift - how to convert an array of objects stored locally (filemanager) to a newer one? (with added attributes) 【发布时间】:2020-05-06 11:07:04 【问题描述】:

所以我一直在研究这个,但仍然一无所获。 基本上,我有一个存储到文件管理器的对象数组。对象,比如 User,有 2 个属性。

class User 
    let firstName: String
    let lastName: String

在新更新时,我添加了新属性。

class User 
    let firstName: String
    let lastName: String
    let age: Int

文件管理器仍然能够识别文件并读取它。但由于它们现在不同,我无法对我的视图控制器进行检查。例如,我想检查这个新用户是否存在于存储的数组中。它将返回 false,因为它们不同。 有什么帮助吗?

编辑: 我的班级确实有和id

class User: Codable, Equatable, Identifiable 
    var id:  firstName 
   // rest of attributes

编辑 2: 这是我的存储和加载数据类

import Foundation
import UIKit

struct DataPersistEngine 

    var users: [User] = []


    struct SavedData: Codable 
        let users: [User]

    

    private let filePath: URL
    private let encoder = JSONEncoder()
    private let decoder = JSONDecoder()

    init() 
        do 
            filePath = try FileManager.default.url(for: .documentDirectory,
                                                   in: .userDomainMask,
                                                   appropriateFor: nil,
                                                   create: false).appendingPathComponent("SavedDatas")
            if let data = try? Data(contentsOf: filePath) 
                decoder.dataDecodingStrategy = .base64
                let savedData = try decoder.decode(SavedData.self, from: data)
                self.users = savedData.users
            
         catch let error 
            fatalError(error.localizedDescription)
        
    

    mutating func saveUser(user: User) 
        if users.contains(user) 
            users.removeAll(where:  $0 == user )
         else 
            users.append(user)
        
        save()
    


    private func save() 
        do 
            let savedData = SavedData(users: users)
            let data = try encoder.encode(savedData)
            try data.write(to: filePath, options: .atomicWrite)
         catch let error 
            print("Error while saving datas: \(error.localizedDescription)")
        
        encoder.dataEncodingStrategy = .base64
    



【问题讨论】:

所以您将您的分类存储到磁盘?显示用于存储和加载 User 对象的代码。 添加了编辑。感谢您的快速回复。 另外,你们有向后兼容的要求吗?例如。如果您的应用程序在 AppStore 中,并且 User 类没有 age 属性,现在您希望添加此属性并让应用程序为老用户正常工作?或者这只是一个宠物项目? :) 我确实想将它发布到应用商店。因为我现在不在我的电脑上,所以我无法帮助尝试“修复”这个错误。但 Joakim 的建议似乎很有希望,我可以从逻辑上看到它的工作。所以不管我加了内容,只要id相等,还是真的。 所以如果这个应用程序还没有发布,只需从你的 iPhone 上删除一个应用程序,然后用 Xcode 重新安装,然后只存储/加载新版本的 User 类就足够了。 【参考方案1】:

实现你自己的定义,让两个对象相等

extension User 
    static func == (lhs: User , rhs: User) -> Bool 
        return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName
     

【讨论】:

所以在我的 tableviewVC 上,我不是这样做:self.users.contains(user),而是这样做? 啊,所以当我在 DataPersistEngine 类上调用 saveUser 函数时会调用它? (见编辑) 您好,刚刚使用建议的代码块进行了测试,进展顺利!谢谢

以上是关于Swift - 如何将本地存储的对象数组(文件管理器)转换为较新的对象? (带有附加属性)的主要内容,如果未能解决你的问题,请参考以下文章

本地存储数组 (Swift)

Swift 中的 iOS 私有/公共数据管理和存储

Swift持久化存储对象到文件中JSONEncoder 与 JSONDecoder

Swift持久化存储对象到文件中JSONEncoder 与 JSONDecoder

Swift持久化存储对象到文件中JSONEncoder 与 JSONDecoder

Swift持久化存储对象到文件中JSONEncoder 与 JSONDecoder