使用ObjectiveC进行JSON解析的弹性

时间:2015-11-25 08:52:25

标签: ios objective-c iphone json

我们的iOS ObjectiveC应用程序使用的JSON API提要有点不稳定,因此有时字段为空。

解析JSON时,我们使用

INotifyPropertyChanged

然后尝试使用例如<。p>的字段

Model

有时候&#34;名称&#34;字段将为null。我们:

1)要求API提供商清理他们的片状API代码

2)每次我们尝试使用json dict

中的内容时检查是否为null
NSDictionary *json = [self JSONFromResponseObject:responseObject];

3)使用try - catch

[widgetIDArray addObject:widget[@"name"][@"id"]];

解答:

感谢下面的答案。这是我添加的NSObject的扩展,它允许我获得可能存在或可能不存在的深层嵌套JSON项。

首先使用类似

的方式调用
if ( ![widget[@"name"] isKindOfClass:[NSNull class]] )

以下是NSObject + extensions.m

中的代码
 @try {
      [widgetIDArray addObject:widget[@"name"][@"id"]];
     }
 @catch (NSException *exception) 
    {
     NSLog(@"Exception %@",exception);
   }

3 个答案:

答案 0 :(得分:2)

JSON响应中的

null不是“片状”,它绝对是标准的。

即使它是“片状”,您从外部收到的任何消息都是攻击媒介,可能允许攻击者入侵您的程序,因此需要弹性。当您收到null时允许对您的应用程序进行DOS攻击时崩溃。

@try / @catch很糟糕。响应编程错误而抛出异常。你没有抓住它们,你修复了你的代码。

如何修复代码?简单。在NSDictionary扩展中编写一些帮助方法。

首先你不知道json是一本字典。所以你添加一个NSDictionary类方法,你传入任何东西,它返回你传递的内容,如果它是一个字典和nil(有适当的日志),如果它是其他任何东西。

接下来,假设键“name”下有一个字典。所以你写了一个扩展名“jsonDictionaryForKey”,如果有的话,它返回一个字典,如果是其他的话,则返回nil(有适当的记录)。

等等。如果您想称自己为专业开发人员,请使您的JSON解析子弹证明。要获得额外的奖励积分,您需要添加一个方法,该方法将获取字典并列出您没有要求的所有存在的键 - 因此您知道您的API是否正在发送您不期望的内容。

答案 1 :(得分:1)

您可以删除JSON对象中的所有NSNULL值。 Here是我在我的库中使用的函数,用于删除JSON对象中的所有空值。

id BWJSONObjectByRemovingKeysWithNullValues(id json, NSJSONReadingOptions options) {
    if ([json isKindOfClass:[NSArray class]]) {
        NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)json count]];
        for (id value in (NSArray *)json) {
            [mutableArray addObject:BWJSONObjectByRemovingKeysWithNullValues(value, options)];
        }

        return (options & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray];
    } else if ([json isKindOfClass:[NSDictionary class]]) {
        NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:json];
        for (id<NSCopying> key in [(NSDictionary *)json allKeys]) {
            id value = [(NSDictionary *)json objectForKey:key];

            if (isNullValue(value)) {
                [mutableDictionary removeObjectForKey:key];
            } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
                [mutableDictionary setObject:BWJSONObjectByRemovingKeysWithNullValues(value, options) forKey:key];
            }
        }

        return (options & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary];
    }

    return json;
}

清除所有空值后,也许异常也会消失。

答案 2 :(得分:0)

经常使用的方法类似于NSDictionaryNSMutableDictionary上的类别,忽略nilNSNull

@interface NSDictionary (nullnilsafe)
- (ObjectType)nullnilsafe_objectForKey:(KeyType)aKey;
@end    

@implementation NSDictionary

- (ObjectType)nullnilsafe_objectForKey:(KeyType)aKey
{
    id obj = [self objectForKey:aKey];
    if (obj && ![obj isKindOfClass:[NSNull class]] ){
        return obj;
    }
    return nil; 
}

@end

@interface NSMutalbeDictionary (nullnilsafe)
- (void)nullnilsafe_setObject:(ObjectType)anObject forKey:(id<NSCopying>)aKey;
@end    

@implementation NSMutalbeDictionary
- (void)nullnilsafe_setObject:(ObjectType)anObject forKey:(id<NSCopying>)aKey
{
    if (anObject && aKey && ![anObject isKindOfClass:[NSNull class]]){
        [self setObject:anObject forKey:aKey];
    }
}

@end