Reputation: 321
I'm new in Swift and iOS and I came across this issue while making an app. I want to basically store user data using NSCoding onto local storage. However, my code below doesn't do it. Anyone can tell me what's wrong with it? Much appreciated!
Also, both saveChecklist and LoadChecklist are called in appDelegate, under applicationDidEnterBackground and applicationWillTerminate.
I have a feeling my issue lies in encodeWithCoder and init(aDecoder), as I used GET to append my Checklist item into lists.
My code in DataModel.class:
import Foundation
class DataModel: NSObject, NSCoding {
var checklist = Checklist()
var lists: [Checklist] {
get {
return [checklist]
}
set {
}
}
override init() {
super.init()
loadChecklist()
}
// MARK: - All the saving stuff
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(checklist, forKey: "Checklist")
}
required init?(coder aDecoder: NSCoder) {
checklist = aDecoder.decodeObjectForKey("Checklist") as! Checklist
}
func documentsDirectory() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
return paths[0]
}
func dataFilePath() -> String {
return (documentsDirectory() as NSString).stringByAppendingPathComponent("Checklist.plist") // create file if no checklist.plist is present
}
func saveChecklist() {
let data = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
archiver.encodeObject(lists, forKey: "Checklists")
archiver.finishEncoding()
data.writeToFile(dataFilePath(), atomically: true)
}
func loadChecklist() {
let path = dataFilePath()
if NSFileManager.defaultManager().fileExistsAtPath(path) {
if let data = NSData(contentsOfFile: path) {
let unarchiver = NSKeyedUnarchiver(forReadingWithData: data)
lists = unarchiver.decodeObjectForKey("Checklists") as! [Checklist]
unarchiver.finishDecoding()
}
}
}
My code in Checklist.class:
import Foundation
class Checklist: NSObject, NSCoding {
var item = [items]()
var rituals = [items]()
var doneButtonVisible: Bool
var streak: Int
var itemDoneCount: Int
var startDate: NSDate
var dayHasStarted: Bool
override init() {
doneButtonVisible = false
itemDoneCount = 0
streak = 0
startDate = NSDate()
dayHasStarted = false
super.init()
}
// saves
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(item, forKey: "Items")
aCoder.encodeObject(rituals, forKey: "Rituals")
aCoder.encodeObject(itemDoneCount, forKey: "ItemDoneCount")
aCoder.encodeObject(doneButtonVisible, forKey: "DoneButtonVisible")
aCoder.encodeObject(streak, forKey: "Streak")
aCoder.encodeObject(startDate, forKey: "StartDate")
aCoder.encodeObject(dayHasStarted, forKey: "DayHasStarted")
}
// loads
required init?(coder aDecoder: NSCoder) {
item = aDecoder.decodeObjectForKey("Items") as! [items]
rituals = aDecoder.decodeObjectForKey("Rituals") as! [items]
itemDoneCount = aDecoder.decodeObjectForKey("ItemDoneCount") as! Int
doneButtonVisible = aDecoder.decodeObjectForKey("DoneButtonVisible") as! Bool
streak = aDecoder.decodeObjectForKey("Streak") as! Int
startDate = aDecoder.decodeObjectForKey("StartDate") as! NSDate
dayHasStarted = aDecoder.decodeObjectForKey("DayHasStarted") as! Bool
super.init()
}
}
UPDATE
Solved the saving and loading issue by revamping my data model. Using Core Data instead to save and load data.
However, I still have no idea as to why the above code does not load. Apparently, it does not save the contents of checklist to begin with.
Upvotes: 1
Views: 456
Reputation: 3773
Your Checklist
class needs to inherit from NSCoding too, and implement the encodeWithCoder(coder: NSCoder)
method. This is a good tutorial on NSCoding.
Upvotes: 1