尝试使用 NSKeyedArchiver 在 UserDefaults 中保存自定义对象

Posted

技术标签:

【中文标题】尝试使用 NSKeyedArchiver 在 UserDefaults 中保存自定义对象【英文标题】:Trying to save custom object in UserDefaults using NSKeyedArchiver 【发布时间】:2020-04-09 08:34:28 【问题描述】:

我想将我的自定义类对象保存在 userdefault 中。 我正在尝试像这样保存它:

class func setModel<T: Hashable>(model: T, key: String) 
    let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: model)
    UserDefaults.standard.set(encodedData, forKey: key)
    UserDefaults.standard.synchronize()

但应用程序在此方法的第一行崩溃并出现错误:

NSForwarding:警告:类“DronesApp_Worker.WorkerProfileResponse”的对象 0x600003944000 未实现 methodSignatureForSelector:-- 前面有问题 无法识别的选择器 -[DronesApp_Worker.WorkerProfileResponse replacementObjectForKeyedArchiver:]

我的自定义对象类如下:

class WorkerProfileResponse: Codable, Hashable, Mappable

    static func == (lhs: WorkerProfileResponse, rhs: WorkerProfileResponse) -> Bool 
        return lhs.id == rhs.id
    

    override var hash: Int
        return self.id!
    

    var id, is_logged_in, last_login, last_active: Int?
    var username, email, mobile_number: String?
    var categoryName: String?
    var userCategories: [SelectedCategory]?
    var userSubCategories: [SelectedSubCategory]?
    var biometricToken: String?
    var accessToken: AccessToken?
    var userStatus: UserStatus?
    var userProfile: UserProfile?

    required init(map: Map) 

    

    func mapping(map: Map) 
        id <- map["id"]
        is_logged_in <- map["is_logged_in"]
        last_login <- map["last_login"]
        last_active <- map["last_active"]
        biometricToken <- map["biometricToken"]
        username <- map["username"]
        email <- map["email"]
        mobile_number <- map["mobile_number"]
        accessToken <- map["accessToken"]
        userStatus <- map["userStatus"]
        userCategories <- map["userCategories"]
        userSubCategories <- map["userSubCategories"]
        userProfile <- map["userProfile"]
    

【问题讨论】:

我已将此行:let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: model) 更改为:let encodedData: Data = try! JSONEncoder().encode(model) 现在它给了我错误:参数类型 'T' 不符合预期的类型 'Encodable' 您需要在您的setModel 声明中将T:Hashable 更改为T:Encodable 【参考方案1】:

使用 JSONEncoder 将数据保存到 UserDefaults。虚拟代码:

class YourClassName: Codable 
    //Your properties here

    func saveInPreference() 
        do 
            let jsonEncoder = JSONEncoder()
            UserDefaults.standard.set(try jsonEncoder.encode(Your object here), forKey: "Write UserDefaultKey here")
            UserDefaults.standard.synchronize()
        
        catch 
            print(error.localizedDescription)
        
    

希望有帮助!

@Faraz A. Khan 如果您对上述代码有任何疑问,请发表评论。

【讨论】:

【参考方案2】:

因为需要NSObject 的子类而发生错误。

正如我在您的previous question 中已经提到的,要使用NSKeyedArchiver,该类必须是NSObject 的子类,并且必须采用(并实现)NSCoding

再次声明:NSKeyedArchiver(与 ObjC 相关)与 Codable(与 Swift 相关)无关。

【讨论】:

以上是关于尝试使用 NSKeyedArchiver 在 UserDefaults 中保存自定义对象的主要内容,如果未能解决你的问题,请参考以下文章

NSKeyedArchiver archiveRootObject 总是返回 NO

NSKeyedArchiver 在 Swift 3 (Xcode 8) 中不起作用

从 NSKeyedArchiver 中提取 NSString

在 NSKeyedArchiver 中查找不同的实例

NSKeyedArchiver 返回 nil Swift 4.2

NSKeyedArchiver 在模拟器中工作,但不在设备中,iOS SDK