Swift,NSCoding 保存类的数组不起作用

Posted

技术标签:

【中文标题】Swift,NSCoding 保存类的数组不起作用【英文标题】:Swift, NSCoding to save array of a class not working 【发布时间】:2016-04-26 14:23:32 【问题描述】:

我是 Swift 和 ios 的新手,在制作应用程序时遇到了这个问题。我想基本上使用 NSCoding 将用户数据存储到本地存储中。但是,我下面的代码并没有这样做。任何人都可以告诉我它有什么问题吗?非常感激!

另外,saveChecklist 和 LoadChecklist 都在 appDelegate 中的 applicationDidEnterBackground 和 applicationWillTerminate 下调用。

我感觉我的问题在于 encodeWithCoder 和 init(aDecoder),因为我使用 GET 将我的 Checklist 项附加到列表中。

我在 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()
        
    

我在 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()

更新

通过修改我的数据模型解决了保存和加载问题。改用 Core Data 来保存和加载数据。

但是,我仍然不知道为什么上面的代码没有加载。显然,它并没有保存清单的内容。

【问题讨论】:

【参考方案1】:

您的Checklist 类也需要继承自NSCoding,并实现encodeWithCoder(coder: NSCoder) 方法。 This 是一个很好的 NSCoding 教程。

【讨论】:

您好,感谢您的回答!但是,我的清单确实继承自 NSCoding,但它仍然不起作用。我会更新帖子以包含它,以便您查看。 好的,你的代码在什么方面不起作用?尝试加载或保存时是否出现错误?还是数据只是错误地重新创建/丢失了一些东西? 没有抛出错误,只是应用程序重新启动时数据未加载或数据未保存开始。如果我没有使用 GET 方法,而只是在 viewController 中的 dataModel 中附加一个清单项,它就可以工作。我相信这与 GET 方法有关。无论如何,我决定使用 Core Data 来存储它,并修改了我的整个数据模型,现在它可以工作了。我仍然不知道为什么上面的代码不起作用。

以上是关于Swift,NSCoding 保存类的数组不起作用的主要内容,如果未能解决你的问题,请参考以下文章

保存 PFObject NSCoding

Swift - URL 数组不起作用

使用 NSCoding 保存结构的 Helperclass

Swift:无法将数组保存到 UserDefaults

在 Swift 中保存数组

Swift 和 NSCoding:对符合类协议的对象数组进行编码