Ios 如何使用NSCoding向现有密钥存档添加新密钥和值

Ios 如何使用NSCoding向现有密钥存档添加新密钥和值,ios,swift,nscoding,Ios,Swift,Nscoding,正在尝试添加新密钥“密码”。应用程序的现有版本具有这些现有键“名称”、“ip”、“端口”,并具有存储值。添加新密钥“密码”时,应用程序无法读取现有数据,并显示此错误“无法解码系统对象的名称”。该错误来自以下代码: guard let password = aDecoder.decodeObject(forKey: PropertyKey.password) as? String else { os_log("Unable to decode the name for a

正在尝试添加新密钥“密码”。应用程序的现有版本具有这些现有键“名称”、“ip”、“端口”,并具有存储值。添加新密钥“密码”时,应用程序无法读取现有数据,并显示此错误“无法解码系统对象的名称”。该错误来自以下代码:

guard let password = aDecoder.decodeObject(forKey: PropertyKey.password) as? String else {
            os_log("Unable to decode the name for a System object.", log: OSLog.default, type: .debug)
            return nil
        }
我的问题是如何添加新密钥“password”,将默认值“123456”分配给所有现有密钥存档(数据/对象),而不销毁现有数据

e.g.
name = "System01", ip = "10.0.0.3", port = "3535", password = "123456" 
name = "System02", ip = "10.0.0.4", port = "3535", password = "123456" 
============================

import UIKit
import os.log

class System: NSObject, NSCoding {


    //MARK: Properties

    var name: String
    var ip: String
    var port: String
    var password: String. // Added this new key

    //MARK: Archiving Paths

    static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
    static let ArchiveURL = DocumentsDirectory.appendingPathComponent("systems")

    //MARK: Types

    struct PropertyKey {
        static let name = "name"
        static let ip = "ip"
        static let port = "port"
        static let password = "password"  // Added this new key
    }

    //MARK: Initialization

    init(name: String, ip: String, port: String, password: String) {

        // Initialize stored properties.
        self.name = name
        self.ip = ip
        self.port = port
        self.password = password  // Added this new key
    }

    //MARK: NSCoding

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: PropertyKey.name)
        aCoder.encode(ip, forKey: PropertyKey.ip)
        aCoder.encode(port, forKey: PropertyKey.port)
        aCoder.encode(password, forKey: PropertyKey.password)  // Added this new key
    }

    required convenience init?(coder aDecoder: NSCoder) {

        // The name is required. If we cannot decode a name string, the initializer should fail.
        guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
            os_log("Unable to decode the name for a System object.", log: OSLog.default, type: .debug)
            return nil
        }
        guard let ip = aDecoder.decodeObject(forKey: PropertyKey.ip) as? String else {
            os_log("Unable to decode the name for a System object.", log: OSLog.default, type: .debug)
            return nil
        }
        guard let port = aDecoder.decodeObject(forKey: PropertyKey.port) as? String else {
            os_log("Unable to decode the name for a System object.", log: OSLog.default, type: .debug)
            return nil
        }
        guard let password = aDecoder.decodeObject(forKey: PropertyKey.password) as? String else {
            os_log("Unable to decode the name for a System object.", log: OSLog.default, type: .debug)
            return nil
        }  // Added this new key

        // Must call designated initializer.
        self.init(name: name, ip: ip, port: port, password: password)

    }
}

在没有密码的情况下,您的代码不需要失败。将
guard let password…
部分替换为以下内容:

let decodedPassword = aDecoder.decodeObject(forKey: PropertyKey.password) as? String
let password = decodedPassword ?? "123456"
然后呢

self.init(name: name, ip: ip, port: port, password: password)

如果您想支持当前应用程序而不发生崩溃,则必须创建从类“System”继承的新类。此外,您还必须通过使用适当的检查对对象进行适当的编码和解码来处理当前场景和未来场景


当然,您可以按照@Gereon中提到的代码进行操作,但如果您想添加更多键值,最好扩展该类。

很明显会发生崩溃。您试图阅读一些不存在的内容,这就是为什么我想知道如何添加新密钥并使其与现有数据一起工作@Gereon提供的答案应该很好。非常感谢Gereon提供的答案!我在三元表达式中得到错误“Expected”:“after'?…”在第行:let password=decodedPassword?“123456”对不起,小字体,这需要读“?”(零合并运算符)有效!!再次感谢你!