Ich bin neu in Swift und iOS und ich stieß auf dieses Problem beim Erstellen einer App. Ich möchte Benutzerdaten grundsätzlich mit NSCoding auf lokalem Speicher speichern. Mein Code unten tut es jedoch nicht. Kann mir jemand sagen, was daran nicht stimmt? Sehr geschätzt!Swift, NSCoding, um Array einer Klasse zu speichern funktioniert nicht
Auch saveChecklist und LoadChecklist werden in appDelegate, unter applicationDidEnterBackground und applicationWillTerminate aufgerufen.
Ich habe das Gefühl, mein Problem liegt in encodeWithCoder und init (aDecoder), wie ich GET verwendet, um meine Checkliste Element in Listen anfügen.
Mein 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()
}
}
}
Mein 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
das Speichern und Laden Problem wurde gelöst indem ich mein Datenmodell überarbeite. Verwenden Sie stattdessen Core Data, um Daten zu speichern und zu laden.
Ich habe jedoch immer noch keine Ahnung, warum der obige Code nicht geladen wird. Anscheinend speichert es nicht den Inhalt der Checkliste, um damit zu beginnen.
Hallo, danke für deine Antwort! Meine Checkliste erbt jedoch von NSCoding und es funktioniert immer noch nicht. Ich aktualisiere den Beitrag, um ihn einzuschließen, damit du ihn überprüfen kannst. –
Ok, auf welche Weise funktioniert dein Code nicht? Wird beim Laden oder Speichern eine Fehlermeldung ausgegeben? Oder werden die Daten nur falsch neu erstellt? – GoatInTheMachine
Es wurde kein Fehler ausgegeben, nur dass die Daten beim Neustart der App nicht geladen wurden oder die Daten nicht gespeichert wurden. Wenn ich die GET-Methode nicht verwende und nur ein Checklistenelement in dataModel in einem viewController anfüge, funktioniert es. Ich glaube, es hat mit der GET-Methode zu tun. Wie auch immer, ich habe beschlossen, Core Data zu verwenden, um es zu speichern, und mein gesamtes Datenmodell überarbeitet und jetzt funktioniert es. Ich habe immer noch keine Ahnung, warum der obige Code nicht funktioniert. –