繁体   English   中英

如何使用UserDefaults.standard保存自定义数据?

[英]How to use UserDefaults.standard save custom Data?

我的资料类别

import Foundation

class People {

let peopleImage : String
let peopleTime : Int
let peopleName : String

init(image:String, second:Int, name:String) {

    peopleImage = image
    peopleTime = second
    peopleName = name

}

我的数据列表文件

import Foundation

class CustomPeopleList {

    var peopleList = [

        People(image: "Man", second: 12, name: "Andy"),
        People(image: "Woman", second: 60, name: "Kevin"),



    ]

}

我的viewController:

let defaults = UserDefaults.standard    
var allPeopleList = CustomPeopleList

有一个按钮,当我单击按钮时,它将删除数据列表中的第一项,但我发现它总是错误。 我的用户默认代码是这样的:

self.allPeopleList.remove(at: indexPathTimer.row)
let aaa = self.allPeopleList
let newPeopleData = NSKeyedArchiver.archivedData(withRootObject: self.allPeopleList)
self.defaults.set(aaa, forKey: "myPeopleData")

当我想使用它时

if let peopleData = defaults.data(forKey: "myPeopleData") as? [People] {
allPeopleList = peopleData
}
var allPeopleList = NSKeyedUnarchiver.unarchiveObject(with: peopleData!) as? [Peoples]

Xcode说错了

我建议使用Codable协议,并将数据另存为JSON。 它比对象-关系swiftier NSKeyed(Un)Archiver

  • 采用协议

     class People : Codable { 
  • 将数组编码为JSON并保存

     do { let newPeopleData = try JSONEncoder().encode(self.allPeopleList) self.defaults.set(newPeopleData, forKey: "myPeopleData") } catch { print(error) 
  • 读取数据也非常简单

     do { if let newPeopleData = self.defaults.data(forKey: "myPeopleData") { allPeopleList = try JSONDecoder().decode([People].self, from: newPeopleData) } } catch { print(error) 

注意:我将以单数形式的Person命名该类,因为People( [People] )的数组是重言式的,并且将属性imagetimename

如果您使用的是NSKeyedArchiverNSKeyedUnarchiver ,则存档的对象必须子类化NSObject并符合NSCoding

您必须执行以下操作:

class People: NSObject, NSCoding {

    let peopleImage : String
    let peopleTime : Int
    let peopleName : String

    init(image:String, second:Int, name:String) {
        peopleImage = image
        peopleTime = second
        peopleName = name
        super.init()
    }

    required init?(coder aDecoder: NSCoder) {
        self.peopleImage = aDecoder.decodeObject(forKey: "peopleImage") as! String
        self.peopleTime = aDecoder.decodeInteger(forKey: "peopleTime")
        self.peopleName = aDecoder.decodeObject(forKey: "peopleName") as! String
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.peopleImage, forKey: "peopleImage")
        aCoder.encode(self.peopleTime, forKey: "peopleTime")
        aCoder.encode(self.peopleName, forKey: "peopleName")
    }
}

class CustomPeopleList: NSObject, NSCoding {

    var peopleList = [
        People(image: "Man", second: 12, name: "Andy"),
        People(image: "Woman", second: 60, name: "Kevin"),
    ]

    override init() {
        super.init()
    }

    required init?(coder aDecoder: NSCoder) {
        self.peopleList = aDecoder.decodeObject(forKey: "peopleList") as! [People]
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.peopleList, forKey: "peopleList")
    }

}

var allPeopleList = CustomPeopleList()

let data = NSKeyedArchiver.archivedData(withRootObject: allPeopleList)

然而

实施NSCoding可能非常冗长。

如果您的对象包括基本实体,例如整数,字符串和可编码实体的数组/字典,那么使用Swift的新Codable协议可能会更容易。

这种方法的优点是,如果您的对象很简单,那么Swift可以为您生成编码和解码方法。

我个人推荐Codable 它比旧的NSCoding方法要简单得多。

看起来像这样:

class People: Codable {

    let peopleImage : String
    let peopleTime : Int
    let peopleName : String

    init(image:String, second:Int, name:String) {
        peopleImage = image
        peopleTime = second
        peopleName = name
    }
}

class CustomPeopleList: Codable {

    var peopleList = [
        People(image: "Man", second: 12, name: "Andy"),
        People(image: "Woman", second: 60, name: "Kevin"),
    ]

}

var allPeopleList = CustomPeopleList()

// Can save in whatever format you want. JSON is always light and simple.
let data = try JSONEncoder().encode(allPeopleList)

// Decode the data object later.
let decodedPeopleList = try JSONDecoder().decode(CustomPeopleList.self, from: data)

使用NSKeyedUnarchiverNSKeyedArchiver时,需要从NSObject继承People类。

要将自定义对象存储在userdefaaults中,您需要继承自定义类形式的NSObject否则会遇到运行时错误/崩溃。

class People: NSObject {


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM