正确检查 NSDictionary 结构

Posted

技术标签:

【中文标题】正确检查 NSDictionary 结构【英文标题】:Properly check NSDictionary structure 【发布时间】:2014-07-07 14:08:15 【问题描述】:

我必须与复杂的 API 和复杂的 JSON 响应进行交互。我正在使用AFNetworking,JSON 响应会自动转换为NSDictionary

我不确定 JSON 结构会始终如我所愿,因此我开始编写大量防御性代码。

if (response &&
    [response isKindOfClass:[NSDictionary class]] &&
    [[response valueForKey:@"result"] isKinfOfClass:[NSString class]]....

我想知道编写一些将空 JSON 响应作为“模板”并检查响应是否与模板“匹配”的代码是否有用。有人处理过这种问题吗?

【问题讨论】:

我会说忘记对 JSON 的验证,而是编写一个由解析的 JSON 数据填充的自定义模型类,然后向自定义模型类添加一个验证方法。这将通过应用程序的开发获得红利。 当然我使用的是自定义类,但这将问题转移到另一个点,你总是必须检查字典的键是否存在,如果值是字符串,布尔值、数字、数组或其他字典,因为 JSON 响应中允许所有这些类型。 嗯,我的意思是在你的模型类中投资代码,忘记“瞬态数据”。您的模型类可能会通过 Core Data 或 JSON 以外的其他方式填充,您可以使用单一的验证方法来检查模型是否正确填充。 【参考方案1】:

为了将值从 JASON 响应插入到核心数据中,我一直在使用这个可以用作函数的类别

@implementation NSManagedObject (safeSetValuesKeysWithDictionary)

- (void)safeSetValuesForKeysWithDictionary:(NSDictionary *)keyedValues

    NSDictionary *attributes = [[self entity] attributesByName];
    for (NSString *attribute in attributes) 
        id value = [keyedValues objectForKey:attribute];
        if (value == nil) 
            // Don't attempt to set nil, or you'll overwite values in self that aren't present in keyedValues
            continue;
        
        NSAttributeType attributeType = [[attributes objectForKey:attribute] attributeType];
        if ((attributeType == NSStringAttributeType) && ([value isKindOfClass:[NSNumber class]])) 
            value = [value stringValue];
         else if (((attributeType == NSInteger16AttributeType) || (attributeType == NSInteger32AttributeType) || (attributeType == NSInteger64AttributeType) || (attributeType == NSBooleanAttributeType)) && ([value isKindOfClass:[NSString class]])) 
            value = [NSNumber numberWithInteger:[value  integerValue]];
         else if ((attributeType == NSFloatAttributeType) && ([value isKindOfClass:[NSString class]])) 
            value = [NSNumber numberWithDouble:[value doubleValue]];
         else if ((attributeType == NSDateAttributeType) && ([value isKindOfClass:[NSString class]])) 
            NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
            [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
            value = [dateFormat dateFromString:[[value componentsSeparatedByString: @"."] objectAtIndex:0]];
         else if ((attributeType == NSDoubleAttributeType) && ([value isKindOfClass:[NSString class]])) 
            value = [NSNumber numberWithDouble:[value doubleValue]];
        

        [self setValue:value forKey:attribute];
    


@end

【讨论】:

以上是关于正确检查 NSDictionary 结构的主要内容,如果未能解决你的问题,请参考以下文章

JSON数据,编辑方式

如何在 iOS 中获取音频文件的持续时间?

哪种检查 NSDictionary 是不是包含特定键的方法更快?

NSDictionary 检查 null

Foundation框架中的动态字典

如何从NSDictionary数组中检查bool值