如何使用UserDefaults.standard保存自定义数据?
How to use UserDefaults.standard save custom Data?
我的数据Class
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说错了
使用NSKeyedUnarchiver
或NSKeyedArchiver
.
时,需要从NSObject继承People
class
要在用户默认值中存储自定义对象,您需要继承自定义 class 形式 NSObject
否则您将获得运行时 error/crashes.
class People: NSObject {
}
我推荐Codable
协议并将数据保存为JSON。它 比 Obj-C 相关 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)
注意:我将 class 命名为单数形式 Person
,因为一组人 ([People]
) 是重言式的,并且将属性命名为 image
, time
和 name
.
如果您使用 NSKeyedArchiver
和 NSKeyedUnarchiver
,那么您归档的对象必须是 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
可能会非常冗长。
如果您的对象包含基本实体,例如整数、字符串和 arrays/dictionaries 可编码实体,那么使用 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)
我的数据Class
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说错了
使用NSKeyedUnarchiver
或NSKeyedArchiver
.
People
class
要在用户默认值中存储自定义对象,您需要继承自定义 class 形式 NSObject
否则您将获得运行时 error/crashes.
class People: NSObject {
}
我推荐Codable
协议并将数据保存为JSON。它 比 Obj-C 相关 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)
注意:我将 class 命名为单数形式 Person
,因为一组人 ([People]
) 是重言式的,并且将属性命名为 image
, time
和 name
.
如果您使用 NSKeyedArchiver
和 NSKeyedUnarchiver
,那么您归档的对象必须是 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
可能会非常冗长。
如果您的对象包含基本实体,例如整数、字符串和 arrays/dictionaries 可编码实体,那么使用 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)