将字典保存到NSUserDefaults中

时间:2014-08-03 22:42:35

标签: swift xcode6

class AddElementVC: UIViewController {

    // textfields and some other functions are defined here 

    @IBAction func addElement(sender: UIBarButtonItem) {

        let newElement = Element(/* properties are defined here */)
        var theDict = NSUserDefaults.standardUserDefaults().dictionaryForKey(tableViewData) as [String: [Element]]

        if var theArray = theDict[newElement.someProperty] {
            theArray += newElement
            theDict[newElement.someProperty] = elementArray
        } else{
            theDict[newElement.someProperty] = [newElement]
        }

        NSUserDefaults.standardUserDefaults().setObject(theDict, forKey: tableViewData)

    }
}

对上述代码的解释:

我的tableView-app从[String:[Element]]类型的字典中接收数据(Element是一个自定义类),它是从userDefaults加载的。在第二个viewController中,您可以填写一些textFields,最后按下UIBarButtonItem。从textFields的数据中创建类“Element”的新实例,并将其添加到“theDict”中的一个“newElement”属性的键上。所有这一切正常,因为我用console-outputs检查它,但我无法最终在userDefaults中保存已编辑的字典。没有语法错误,但是当我使用应用程序并尝试通过第二个viewController向Dictionary添加另一个元素时,会显示以下错误:

错误消息:

NSForwarding:警告:类'_TtC12myApp7Element'的对象0xdcb002c没有实现methodSignatureForSelector: - 提前麻烦

研究并没有帮助我理解错误信息。

修改

import Foundation

class Element: NSCoding {

enum State: String {
    case state1 = "state1"
    case state2 = "state2"
}

let state: State
// some more properties

init(state: String /* something more */ ){
    self.state = State.fromRaw(state)!
    // something more
}

init(coder aDecoder: NSCoder!) {
    self.state = aDecoder.decodeObjectForKey("state") // displays error: 'AnyObject' is not convertible to 'Element.State'
    // something more
}

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(self.state, forKey: "state") // displays error: Extra Argument 'forKey' in call
    // something more
}

}

1 个答案:

答案 0 :(得分:14)

来自NSUserDefaults documentation

  

value参数只能是属性列表对象:NSData,   NSString,NSNumber,NSDate,NSArray或NSDictionary。对于NSArray和   NSDictionary对象,其内容必须是属性列表对象。   请参阅“What is a Property List?”中的Property List Programming Guide

您无法在字典中存储包含Element元素的字典。

一个选项是确保Element实现NSCoding protocol,然后使用NSKeyedArchiver将字典转换为NSData:

// Storing the dictionary
var data = NSKeyedArchiver.archivedDataWithRootObject(theDict)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: tableViewData)

// Retrieving the dictionary
var outData = NSUserDefaults.standardUserDefaults().dataForKey(tableViewData)
var dict = NSKeyedUnarchiver.unarchiveObjectWithData(outData)

您的协议实现看起来像这样:

init(coder aDecoder: NSCoder!) {
    self.state = State.fromRaw(aDecoder.decodeObjectForKey("state") as String)
}

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeObject(self.state.toRaw(), forKey: "state")
}

您不能存储枚举,但您可以存储它的原始表示形式。