我可以在 UserDefaults 上存储哪种字典或数组有任何限制吗?

Is there any limitation of what kind of Dictionary or Array I can store on UserDefaults?

我有一个来自 Json 的 Dictionary 我想存储在 UserDefaults 上,但我收到错误 Attempt to set a non-property-list object <object description here> as an NSUserDefaults/CFPreferences value for key info.

问题是,我的 Dictionary 是一个多层嵌套 Dictionary,其中也有 Array。但是在叶节点上,all 只是 String。大概是这样的结构。

{
    data: {
        field1: "...",
        field2: "...",
        field3: [
            {
                info1: "...",
                info2: "...",
                info3: "..."
            },
            {
                info1: "...",
                info2: "...",
                info3: "..."
            }
        ]
    }
}

这个格式不能存入UserDefaults吗?

谢谢。

编辑:当我缩小问题范围时,问题似乎出在 field3 的个别行中。当我试图保存 field3 ex: field3[0] 的单个行的字典时,它给了我同样的错误。但是如果我保存整个 json 并删除 field3(设置为 nil),我没有问题。

这里是field3一行的实际内容。

{
    "app_setting" = "app_setting_1";
    "created_at" = "2017-02-02 19:54:46";
    "feedback_name" = "No Toilet Paper";
    "feedback_option" = 1;
    id = "feedback_option_11";
    property = "property_1";
    sn = "<null>";
    "updated_at" = "2017-02-02 19:54:46";
    "url_image_option" = "https://example.com/assets/ios/option1.png";
}

我们可以设置字典,不管里面有什么,比如字符串,数组。

Objective C

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
[currentDefaults setObject:urDictionary forKey:@"yourKeyName"];

NSUserDefaults *retrieveDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *data1 = [retrieveDefaults objectForKey:@"yourKeyName"];

先确定是字典

将对象转换为 NSData

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:urObject];

检索对象

NSData *data1 = [retrieveDefaults objectForKey:@"yourKeyName"];
urObject *retrievedModel = [NSKeyedUnarchiver unarchiveObjectWithData:data1];

Swift 3.0

将字典转换为数据

let dataExample: Data = NSKeyedArchiver.archivedData(withRootObject: dictionaryExample)
NSUserDefaults.standardUserDefaults().setObject(dataExample, forKey:"yourKey")

检索数据:

NSUserDefaults.standardUserDefaults().objectForKey("yourKey") as! NSDate
let dictionary: Dictionary? = NSKeyedUnarchiver.unarchiveObject(with: dataExample) as! [String : Any]

苹果是这么说的

The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list—that is, an instance of (or for collections, a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.

只要您使用 DictionaryUserDefaults Documentation 中列出的其他受支持的数据类型,就应该没问题。如果是这种情况并且它仍然给出错误,则说明您构建的字典不正确。

这个解决方案工作正常:

let dict: [String:Dictionary] = [
            "data": [
                "field1":["a","b","c"],
                "field2":["d","e","f"]
            ],
            "otherData": [
                "field1":["g","h","i"],
                "field2":["j","k","l"]
            ]
        ]

UserDefaults.standard.set(dict, forKey: "dict")
UserDefaults.standard.synchronize()