My 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
}
My Data List File
import Foundation
class CustomPeopleList {
var peopleList = [
People(image: "Man", second: 12, name: "Andy"),
People(image: "Woman", second: 60, name: "Kevin"),
]
}
my viewController :
let defaults = UserDefaults.standard
var allPeopleList = CustomPeopleList
There is a button, when I click button it will delete the first item in the Data List, but I find it always error. my userdefault code is this:
self.allPeopleList.remove(at: indexPathTimer.row)
let aaa = self.allPeopleList
let newPeopleData = NSKeyedArchiver.archivedData(withRootObject: self.allPeopleList)
self.defaults.set(aaa, forKey: "myPeopleData")
and when i want to use it
if let peopleData = defaults.data(forKey: "myPeopleData") as? [People] {
allPeopleList = peopleData
}
var allPeopleList = NSKeyedUnarchiver.unarchiveObject(with: peopleData!) as? [Peoples]
the xcode say it wrong
I recommend the Codable
protocol and to save the data as JSON. It's swiftier than Obj-C related NSKeyed(Un)Archiver
Adopt the protocol
class People : Codable {
Encode the array as JSON and save it
do { let newPeopleData = try JSONEncoder().encode(self.allPeopleList) self.defaults.set(newPeopleData, forKey: "myPeopleData") } catch { print(error)
To read the data is very simple, too
do { if let newPeopleData = self.defaults.data(forKey: "myPeopleData") { allPeopleList = try JSONDecoder().decode([People].self, from: newPeopleData) } } catch { print(error)
Note: I'd name the class in singular form Person
because an array of People ( [People]
) is tautologic and to name the properties image
, time
and name
.
If you're using NSKeyedArchiver
and NSKeyedUnarchiver
, then the objects you archive must subclass NSObject
and conform to NSCoding
.
You'd have to do something like this:
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)
However
Implementing NSCoding
can be very verbose.
If your objects include basic entities, like integers, strings, and arrays/dictionaries of encodable entities, then it may be easier to use Swift's new Codable
protocol.
The advantage of this method is that if your objects are simple, then Swift can generate the encode and decode methods for you.
I personally recommend Codable
. It can be much simpler than the old NSCoding
method.
That would look like this:
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)
You need to inherit People
class from NSObject when you are using NSKeyedUnarchiver
or NSKeyedArchiver
.
To store custom object in userdefaaults you need to inherit custom class form NSObject
otherwise you will get runtime error/crashes.
class People: NSObject {
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.