【问题标题】:Saving NSDictionary from json result to NSUserDefaults return "attempt to insert non-property list object" error将 NSDictionary 从 json 结果保存到 NSUserDefaults 返回“尝试插入非属性列表对象”错误
【发布时间】:2014-06-02 08:10:53
【问题描述】:

你好,我有这样的 json 数据

来自 NSLog(@"JSON sec blnce list: %@", responseObject);:

{
detail =     (
            {
        account = 9X000101300160;
        balance = "1.000.000";
        date = "<null>";
        price = 0;
        secCode = 9999;
        type = Blocked;
        value = 0;
    },
            {
        account = 9X000101300160;
        balance = "1.000.000";
        date = "<null>";
        price = 0;
        secCode = 9999;
        type = Available;
        value = 0;
    }
);
header =     {
    date = 24092012;
    investorID = IDD010239865303;
    securityType = Equity;
};
}

我想要做的是将这个 json 结果保存到 NSUserDefaults 中。这是我的保存方式: 在.h

@property NSDictionary *jsonResult;

在.m

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

        [manager POST:URI_SECURITY_BALANCE_DETAIL parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {

            [SVProgressHUD dismiss];


            NSLog(@"JSON sec blnce list: %@", responseObject);

            self.jsonResult = responseObject;

            //simpan hasil query ke device
            NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
            [defaults setObject:self.jsonResult forKey:@"securityBalanceNextJsonResult"];
            [defaults synchronize];

但上面的代码给了我一个错误:“尝试设置一个非属性列表对象”

如何将我从 json 结果中获得的 NSDictionary 保存到 NSUserDefaults 中??

更新:(已解决) 可能有人有同样的问题,这是我的工作代码:

self.jsonResult = responseObject;

        NSData *data = [NSJSONSerialization dataWithJSONObject:self.jsonResult options:kNilOptions error:nil];
        [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"securitiesBalanceJsonResult"];

        NSError* error;
        NSDictionary* jsonDB = [NSJSONSerialization
                              JSONObjectWithData:[defaults objectForKey:@"securitiesBalanceJsonResult"]

                              options:kNilOptions 
                              error:&error];

        NSLog(@"data:%@",jsonDB);

【问题讨论】:

  • 什么是 NSLog(@"JSON sec blnce list: %@", responseObject);打印?
  • 我在第一段 JSON sec blnce 列表中提到的打印 json 数据:{ detail = ( { account = 9X000101300160; balance = "1.000.000"; date = ""; price = 0 ; secCode = 9999; type = Blocked; value = 0; }, { account = 9X000101300160; balance = "1.000.000"; date = ""; price = 0; secCode = 9999; type = Available; value = 0;});标头 = { 日期 = 24092012;投资者ID = IDD010239865303;证券类型 = 股权; }; }
  • 你应该从你的响应中创建一个合适的模型对象,然后在将其转换为 nsdata 后将其存储在 nsuserdefault 中。
  • @pawan:对我来说似乎是对的,因为它最好构建一个模型并且易于存储和检索信息。
  • @NhonNguyen 正确,现在你走在了正确的轨道上。如果您需要任何帮助,请在此处告诉我。祝你好运!

标签: ios objective-c


【解决方案1】:

我能想到的唯一解释是您的服务器在 JSON 中向您发送空值。当结果转换为 NSDictionary 时,NSNull 的实例将插入到字典中以表示这些空值。

但是,NSNull 不是属性值,这就是您无法将字典存储在用户默认值上的原因。正如NSUserDefaults documentation 所说:

NSUserDefaults 类提供了方便的访问方法 常见类型,例如浮点数、双精度数、整数、布尔值和 URL。一种 默认对象必须是一个属性列表,即(或 对于集合实例的组合):NSData,NSString, NSNumber、NSDate、NSArray 或 NSDictionary。如果你想存储任何 其他类型的对象,您通常应该将其归档以创建一个 NSData 的实例。

你有两个选择:

  1. 删除带有空值的键(在示例中,detail 中的两个 dates)。
  2. 将字典另存为NSData

对于第一个:

NSMutableDictionary *mutable = [dictionary mutableCopy];
NSArray *array = mutable[@"detail"];
NSMutableArray *mut = [NSMutableArray arrayWithCapacity:[array count]];
for (NSDictionary *d in array)
{
    NSMutableDictionary *m = [NSMutableDictionary dictionary];
    for (NSString *k in d) {
        id v = d[k];
        if (![v isKindOfClass:[NSNull class]]) {
            m[k] = v;
        }
    }
    [mut addObject:m];
}
mutable[@"detail"] = mut;

第二个:

NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:nil];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];

【讨论】:

  • "" 是一个字符串,而不是 NSNull。你不这么认为吗?
  • "" 是 NSNull 实例作为其描述返回的内容。如果你记录一个 NSNull,这就是你将在控制台中得到的。
  • 我不这么认为,因为如您所见,json 是通过调用 web 服务来检索的。并且“”由服务器作为 json 结构中的字符串返回。
  • 是的,你是对的“”是它出错的原因。在我的测试应用程序中更改空值时,我没有收到任何错误。但问题出在我的真实应用程序中,我无法更改该空值,因为我是从服务器接收到的。如果成功,我会尝试第二个选项并在此处更新
  • @NhonNguyen 因为标题是指保存 NSDictionary 并且日志不是有效的 JSON,而是字典打印的类似结果,所以我推断 responseObject 是一个 NSDictionary。知道 NSNull 实例无法保存为用户默认值,我得出结论,最合理的解释(如果不是唯一的)是“”不是字符串,而是 NSNull 的描述。我已经更新了答案以澄清这一点。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
相关资源
最近更新 更多