[英]How to store array list of custom objects to NSUserDefaults?
class Item
{
var name: String
var collectionId: Int
init(name: String, collectionId: Int) {
self.name = name
self.collectionId = collectionId
}
}
class ViewController:UIViewController
{
var itemList = [Item]()
func recievedResults()
{
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(self.itemList, forKey: "myList")
}
}
我收到错误消息“属性列表不能包含‘CFType’类型的对象”
如何将 itemList 存储和获取到 NSUserDefaults?
首先,您必须使用编码器和解码器方法从 NSObject 继承 Item:
class Item :NSObject
{
var name: String = ""
var collectionId: Int = 0
init(name: String, collectionId: Int) {
self.name = name
self.collectionId = collectionId
}
init(coder decoder: NSCoder) {
self.name = decoder.decodeObjectForKey("name") as String
self.collectionId = decoder.decodeIntegerForKey("collectionId")
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeInt(Int32(self.collectionId), forKey: "collectionId")
}
}
然后,这些是从 NSUserDefaults 插入和检索的函数。
func insertItems()
{
let defaults = NSUserDefaults.standardUserDefaults()
let data = NSKeyedArchiver.archivedDataWithRootObject(itemList)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "myList")
}
func retrieveItems()
{
let defaults = NSUserDefaults.standardUserDefaults()
if let data = NSUserDefaults.standardUserDefaults().objectForKey("myList") as? NSData {
let _mySavedList = NSKeyedUnarchiver.unarchiveObjectWithData(data) as [Item]
}
}
例子:
let item1 = Item(name: "Item 1", collectionId: 1)
let item2 = Item(name: "Item 2", collectionId: 2)
itemList.append(item1)
itemList.append(item2)
insertItems()
retrieveItems()
从Swift 4 开始,使用Codable变得更加容易:
import Foundation
//Declaration
struct Item: Codable {
var name: String
var collectionId: Int
}
//Initialization
let itemA: Item = Item.init(name: "Bob A.", collectionId: 1)
let itemB: Item = Item.init(name: "Bob B.", collectionId: 1)
let items: [Item] = [itemA, itemB]
//Storing Items
if let encoded = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encoded, forKey: "items")
}
//Retrieving Items
do {
let storedObjItem = UserDefaults.standard.object(forKey: "items")
let storedItems = try JSONDecoder().decode([Item].self, from: storedObjItem as! Data)
print("Retrieved items: \(storedItems)")
} catch let err {
print(err)
}
您需要为您的自定义类实现协议 NSCoding。 请参阅此Swift 示例。
正如在此堆栈溢出问题中指出的,您不能在 NSUserDefaults 中存储自定义对象。
但是你可以让你的类 NSCoding 兼容并存储来自 NSKeyedArchiver.archivedDataWithRootObject(...) 的 NSData:
class Item : NSObject, NSCoding {
var name: String
var collectionId: Int
init(name: String, collectionId: Int) {
self.name = name
self.collectionId = collectionId
}
required init(coder aDecoder: NSCoder) {
collectionId = aDecoder.decodeIntegerForKey("collectionId")
name = aDecoder.decodeObjectForKey("name") as String
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: "name")
aCoder.encodeInteger(collectionId, forKey: "collectionId")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
recievedResults()
}
var itemList = [Item]()
func recievedResults()
{
self.itemList.append(Item(name: "test", collectionId: 2))
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(NSKeyedArchiver.archivedDataWithRootObject(itemList), forKey: "myList")
let data = defaults.objectForKey("myList") as NSData
if let decodedList = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [Item]{
print("first item: \(decodedList)")
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.