在我的应用程序中,我正在尝试序列化服务器响应字典并将其写入文件系统。但是我收到一些回复的错误“属性列表格式无效”。原因是服务器响应中的CFNull对象。现在,服务器响应将继续改变,所以我没有明确的方法来删除CFNull对象()。以下是我的代码:
NSString *anError = nil;
NSData *aData = [NSPropertyListSerialization dataFromPropertyList:iFile format:NSPropertyListXMLFormat_v1_0 errorDescription:&anError];
解决此问题的最佳方法是什么?如何一次性从服务器响应中删除所有CFNull对象?
答案 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属性列表或按下应用程序中的数据,以便将其正确解释为属性列表。