Swift3 使用NSCoding保存带有自定义对象的数组
我正在制作一个待办事项列表应用程序来了解细节,它有一个简单的列表和项目结构。我使用3个类来管理它们:Swift3 使用NSCoding保存带有自定义对象的数组,swift3,ios10,Swift3,Ios10,我正在制作一个待办事项列表应用程序来了解细节,它有一个简单的列表和项目结构。我使用3个类来管理它们: ToDomainManager:是一个单例,用于集中管理我的视图控制器中的列表和列表中的项。它包含一个todolist数组和一组函数,用于添加列表、将它们标记为已完成列表并返回列表 TodoList:有一个字符串变量(name)、bool变量(completed)和一个TodoItems数组 TodoItem:具有字符串变量(名称)和布尔变量(已完成) 我想存储我的自定义对象数组[TodoL
- ToDomainManager:是一个单例,用于集中管理我的视图控制器中的列表和列表中的项。它包含一个todolist数组和一组函数,用于添加列表、将它们标记为已完成列表并返回列表
- TodoList:有一个字符串变量(name)、bool变量(completed)和一个TodoItems数组
- TodoItem:具有字符串变量(名称)和布尔变量(已完成)
class TodoManager: NSObject, NSCoding {
// the singleton
static let shared = TodoManager()
// filePath var
private var filePath : String {
let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
return url.appendingPathComponent("objectsArray").path
}
// init
override private init() {}
// array to store all lists
private var lists = [TodoList]()
func newTodoList(title: String) {
lists.append(TodoList(instanceTitle: title))
}
// coding
func encode(with coder: NSCoder) {
coder.encode(lists, forKey: "lists")
}
required convenience init(coder decoder: NSCoder) {
self.init()
lists = decoder.decodeObject(forKey: "lists") as! [TodoList]
}
// saving and loading
func saveAll() {
let data = lists
NSKeyedArchiver.archiveRootObject(data, toFile: filePath)
}
func loadAll() {
if let dataArray = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? [TodoList] {
lists = dataArray
}
}
}
class TodoList: NSObject, NSCoding {
// array to store items in this list instance
private var items = [TodoItem]()
// vars to store title and completion status
private var title = String()
private var completed = Bool()
// init
init(instanceTitle: String) {
title = instanceTitle
completed = false
}
// coding
func encode(with coder: NSCoder) {
coder.encode(items, forKey: "lists")
coder.encode(title, forKey: "title")
coder.encode(completed, forKey: "completed")
}
required convenience init(coder decoder: NSCoder) {
self.items = decoder.decodeObject(forKey: "items") as! [TodoItem]
self.title = decoder.decodeObject(forKey: "title") as! String
self.completed = decoder.decodeBool(forKey: "completed")
self.init() // <----- critical line
}
// item-related
func addItem(title: String) {
items.append(TodoItem(instanceTitle: title))
}
}
class TodoItem: NSObject, NSCoding {
private var title = String()
private var completed = Bool()
// inits
init(instanceTitle: String) {
title = instanceTitle
completed = false
}
func encode(with coder: NSCoder) {
coder.encode(title, forKey: "title")
coder.encode(completed, forKey: "completed")
}
required convenience init(coder decoder: NSCoder) {
self.init() // <----- similar critical line
title = decoder.decodeObject(forKey: "title") as! String
completed = decoder.decodeBool(forKey: "completed")
}
}
类ToDomainManager:NSObject,NSCoding{
//单身汉
静态let shared=ToDomainManager()
//文件路径变量
私有变量文件路径:字符串{
让url=FileManager.default.url(对于:.documentDirectory,在:.userDomainMask中)。首先!
返回url.appendingPathComponent(“objectsArray”).path
}
//初始化
重写私有init(){}
//数组来存储所有列表
私有变量列表=[TodoList]()
func新代码列表(标题:字符串){
lists.append(TodoList(instanceTitle:title))
}
//编码
func编码(带编码器:NSCoder){
编码(列表,forKey:“列表”)
}
所需便利初始化(编码器-解码器:NSCoder){
self.init()
lists=decoder.decodeObject(forKey:“lists”)为![TodoList]
}
//保存和加载
func saveAll(){
让数据=列表
归档对象(数据,toFile:filePath)
}
func loadAll(){
如果让dataArray=NSKeyedUnarchiver.unarchiveObject(带文件:filePath)作为?[TodoList]{
列表=数据数组
}
}
}
类TodoList:NSObject,NSCoding{
//数组来存储此列表实例中的项
私有变量项=[TodoItem]()
//存储标题和完成状态的变量
私有变量title=String()
private var completed=Bool()
//初始化
init(instanceTitle:String){
title=instanceTitle
已完成=错误
}
//编码
func编码(带编码器:NSCoder){
编码器编码(项目,forKey:“列表”)
编码员编码(标题,福基:“标题”)
编码器编码(已完成,forKey:“已完成”)
}
所需便利初始化(编码器-解码器:NSCoder){
self.items=decoder.decodeObject(forKey:“items”)as![TodoItem]
self.title=decoder.decodeObject(forKey:“title”)作为!字符串
self.completed=decoder.decodeBool(forKey:“completed”)
self.init()//调用便利的
初始值设定项()
时,实际参数最初传递给指定的init()
由请求创建类的新实例的函数调用,无需通过便利初始化。您可以使用占位符调用指定的初始值设定项,该占位符在执行时填充。对于我的情况,它如下所示:
init(instanceTitle: String) {
title = instanceTitle
completed = false
}
required convenience init(coder decoder: NSCoder) {
// call designated init
self.init(instanceTitle: "[placeholder]")
items = decoder.decodeObject(forKey: "items") as! [TodoItem]
title = decoder.decodeObject(forKey: "title") as! String
completed = decoder.decodeBool(forKey: "completed")
}