在NSPropertyListSerialization中处理CFNull对象

时间:2011-06-05 18:19:25

标签: iphone objective-c cocoa-touch nsdata property-list

在我的应用程序中,我正在尝试序列化服务器响应字典并将其写入文件系统。但是我收到一些回复的错误“属性列表格式无效”。原因是服务器响应中的CFNull对象。现在,服务器响应将继续改变,所以我没有明确的方法来删除CFNull对象()。以下是我的代码:

NSString *anError = nil;
NSData *aData = [NSPropertyListSerialization dataFromPropertyList:iFile format:NSPropertyListXMLFormat_v1_0 errorDescription:&anError];

解决此问题的最佳方法是什么?如何一次性从服务器响应中删除所有CFNull对象?

4 个答案:

答案 0 :(得分:9)

我从Facebook SDK收到回复时遇到了这个问题,所以我实现了这个方法:

- (void)cleanDictionary:(NSMutableDictionary *)dictionary {
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if (obj == [NSNull null]) {
        [dictionary setObject:@"" forKey:key];
    } else if ([obj isKindOfClass:[NSDictionary class]]) {
        [self cleanDictionary:obj];
    }
}];

}

这将走向字典的层次结构,并将所有CFNulls转换为空字符串。

答案 1 :(得分:4)

我切换到NSKeyedArchiver选项。比NSPropertyListSerialization慢一点但是要处理NSNull / CFNull对象。

答案 2 :(得分:1)

我写了一个类别来清理字典:

-(NSDictionary*)cleanDictionary
{
    return [NSDictionary cleanDictionary:self];
}

+ (NSDictionary*)cleanDictionary:(NSDictionary *)dictionary
{
    NSMutableDictionary *dict = [NSMutableDictionary new];

    [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        if (obj == [NSNull null])
        {
            //dont add it
        }

        else if ([obj isKindOfClass:[NSDictionary class]])
        {
            [dict setObject:[self cleanDictionary:obj] forKey:key];
        }
        else if ([obj isKindOfClass:[NSArray class]])
        {
            [dict setObject:[NSDictionary cleanArray:obj] forKey:key];
        }
        else {
            [dict setObject:obj forKey:key];
        }
    }];

    return dict;
}

+(NSArray*)cleanArray:(NSArray*)array
{
    NSMutableArray* returnArray = [NSMutableArray new];

    for (NSObject *obj in array)
    {
        if (obj == [NSNull null])
        {
           //dont add it
        }
        if ([obj isKindOfClass:[NSDictionary class]])
        {
            [returnArray addObject:[NSDictionary cleanDictionary:(NSDictionary*)obj]];
        }
        else if ([obj isKindOfClass:[NSArray class]])
        {
            [returnArray addObject:[NSDictionary cleanArray:(NSArray*)obj]];
        }
        else
        {
            [returnArray addObject:obj];
        }
    }
    return returnArray;
}

答案 3 :(得分:0)

如果您无法通过datafromPropertyList:... API序列化,那么它不是属性列表。

将服务器响应修复为barf up up属性列表或按下应用程序中的数据,以便将其正确解释为属性列表。