Ios 使用NSUserDefaults应用程序保存阵列
我觉得我做的事情是正确的,但在数据转换和检索结束时,我遇到了一个错误。请参阅下面的代码:Ios 使用NSUserDefaults应用程序保存阵列,ios,arrays,swift,nsuserdefaults,saving-data,Ios,Arrays,Swift,Nsuserdefaults,Saving Data,我觉得我做的事情是正确的,但在数据转换和检索结束时,我遇到了一个错误。请参阅下面的代码: class Task:NSObject, NSCoding { var name:String var notes:String var date:NSDate var taskCompleted:Bool init(name:String, notes:String,date:NSDate, taskCompleted:Bo
class Task:NSObject, NSCoding {
var name:String
var notes:String
var date:NSDate
var taskCompleted:Bool
init(name:String, notes:String,date:NSDate, taskCompleted:Bool){
self.name = name
self.notes = notes
self.date = date
self.taskCompleted = taskCompleted
}
required init(coder decoder: NSCoder){
self.name = (decoder.decodeObjectForKey("name") as! String?)!
self.notes = (decoder.decodeObjectForKey("notes") as! String?)!
self.date = (decoder.decodeObjectForKey("date") as! NSDate?)!
self.taskCompleted = (decoder.decodeObjectForKey("taskCompleted") as! Bool?)!
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeObject(self.notes, forKey: "notes")
coder.encodeObject(self.date, forKey: "date")
coder.encodeObject(self.taskCompleted, forKey: "taskCompleted")
}
}
然后,我按如下方式保存并获取数据:
let nowData = NSKeyedArchiver.archivedDataWithRootObject([nowTasks])
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(nowData, forKey: "nowData")
let loadedData = defaults.dataForKey("nowData")
let loadedArray = NSKeyedUnarchiver.unarchiveObjectWithData(loadedData!) as! [Task]
当我调用
print(loadedaray.first)
时,我得到了一个错误:NSArray元素与Swift数组元素类型不匹配看起来你的代码应该可以正常工作,即使你的解码器方法中发生了一些非常奇怪的强制转换。试着这样做:
class Task: NSObject, NSCoding {
var name = String()
var notes = String()
var date: NSDate
var taskCompleted: Bool
init(name: String, notes: String, date: NSDate, taskCompleted: Bool){
self.name = name
self.notes = notes
self.date = date
self.taskCompleted = taskCompleted
}
required init(coder decoder: NSCoder){
self.name = decoder.decodeObjectForKey("name") as! String
self.notes = decoder.decodeObjectForKey("notes") as! String
self.date = decoder.decodeObjectForKey("date") as! NSDate
self.taskCompleted = decoder.decodeBoolForKey("taskCompleted")
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(name, forKey: "name")
coder.encodeObject(notes, forKey: "notes")
coder.encodeObject(date, forKey: "date")
coder.encodeBool(taskCompleted, forKey: "taskCompleted")
}
}
使用plist文件进行测试:
let task1 = Task(name: "task1", notes: "note a", date: NSDate(), taskCompleted: false)
let task2 = Task(name: "task2", notes: "note b", date: NSDate(), taskCompleted: true)
let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let fileURL = documentsDirectory.URLByAppendingPathComponent("data.plist")
if let filePath = fileURL.path {
NSKeyedArchiver.archiveRootObject([task1,task2], toFile: filePath)
if let loadedArray = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? [Task] {
print(loadedArray.count)
print(loadedArray.first?.name ?? "")
print(loadedArray.first?.notes ?? "")
print(loadedArray.first!.date )
print(loadedArray.first!.taskCompleted)
print(loadedArray.last?.name ?? "")
print(loadedArray.last?.notes ?? "")
print(loadedArray.last!.date )
print(loadedArray.last!.taskCompleted)
}
}
当控制台崩溃时,将打印的消息发布到控制台,您必须实现
NSCoding
协议,以使用上面添加的NSKeyedArchiver
错误代码归档类。您需要实现NSCoding
协议,并在一段时间后使您的任务成为NSObject
的子类使用上面的代码,我成功地使它工作。再次感谢!还有一个问题。我可以使用相同的.plist文件保存多个数组吗?我是否使用相同的NSKeyedArchiver.archiveRootObject(myArray,toFile:filePath)
检索相同的文件路径?可以,但我认为对每个数组使用plist文件会更容易。您可以将plist文件保存在库目录的preferences文件夹中