我收到一个JSON字符串,我需要迭代以检索一些对象值。 这是结构
-meta -objects |_cabdriver |_employee |client
对象树下有对象,还有子节点,如cabdriver和client。子节点cabdriver还有另一个名为employee的子节点。
这是我迭代它的方式:
NSArray *messageArray = [json objectForKey:@"objects"];
historialServicios = [[NSMutableArray alloc]init];
// Parse and loop through the JSON
for (dictionary in messageArray) {
//datos de nivel objects
NSString * date = [dictionary objectForKey:@"date"];
NSString * origin = [dictionary objectForKey:@"origin"];
NSString * destiny = [dictionary objectForKey:@"destiny"];
NSString * rate = [dictionary objectForKey:@"service_rate"];
NSString * state = [dictionary objectForKey:@"state"];
NSString * time_service = [dictionary objectForKey:@"time_service"];
NSString * id_service = [dictionary objectForKey:@"id"];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary objectForKey:@"client"];
NSString *client_id = [level2Dict objectForKey:@"id"];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary objectForKey:@"cabdriver"];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
//datos del employee
NSString *driverName = [employeeLevelDict objectForKey:@"name"];
NSString *driverLastname = [employeeLevelDict objectForKey:@"lastname"];
NSString *driverPhone = [employeeLevelDict objectForKey:@"phone"];
NSString *driverId = [employeeLevelDict objectForKey:@"id"];
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
NSLog(@"DESPUES DE ANADIR OBJETOS");
NSLog(@"OBJETO ANADIDO==>TIME SERVICE = %@, ID SERVICE=%@, SERVICE RATE=%@,SERVICE DATE=%@,DESTINY=%@, STATE =%@,CLIENT ID=%@, ORIGIN=%@,DRIVER NAME=%@, DRIVER LASTNAME=%@,DRIVER PHONE=%@, DRIVER ID=%@",time_service,id_service,rate,date,destiny,state,client_id,origin,driverName,driverLastname,driverPhone,driverId);
//insertamos objetos en diccionario historialServicios
}
如果对象具有所有节点但是有时候节点cabdriver为空并且没有雇员子节点,则一切正常。如果是这种情况,我会抛出异常并且应用程序崩溃。
我如何确定节点员工是否不存在并避免获得例外?
谢谢。
答案 0 :(得分:2)
您可以声明一个类别来处理注入json的[NSNull null]
值。
@interface NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key;
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue;
@end
@implementation NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key {
return [self optionalObjectForKey:key defaultValue:nil];
]
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue {
id obj = [self objectForKey:key];
return (obj == [NSNull null] || !obj) ? defaultValue : obj;
}
@end
然后使用它:
NSDictionary *cabdriverLevelDict = [dictionary optionalObjectForKey:@"cabdriver"];
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee"];
您尚未发布异常内容,但从外观来看,这可能与尝试将nil
值添加到新词典有关。
然后对所有数据查找使用默认值[NSNull null]
,这些数据查找将生成用于构造最终字典的对象。完整查找源现在将如下所示:
NSString * date = [dictionary optionalObjectForKey:@"date" defaultValue:[NSNull null]];
NSString * origin = [dictionary optionalObjectForKey:@"origin" defaultValue:[NSNull null]];
NSString * destiny = [dictionary optionalObjectForKey:@"destiny" defaultValue:[NSNull null]];
NSString * rate = [dictionary optionalObjectForKey:@"service_rate" defaultValue:[NSNull null]];
NSString * state = [dictionary optionalObjectForKey:@"state" defaultValue:[NSNull null]];
NSString * time_service = [dictionary optionalObjectForKey:@"time_service" defaultValue:[NSNull null]];
NSString * id_service = [dictionary optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary optionalObjectForKey:@"client" defaultValue:[NSDictionary dictionary]];
NSString *client_id = [level2Dict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary optionalObjectForKey:@"cabdriver" defaultValue:[NSDictionary dictionary]];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee" defaultValue:[NSDictionary dictionary]];
//datos del employee
NSString *driverName = [employeeLevelDict optionalObjectForKey:@"name" defaultValue:[NSNull null]];
NSString *driverLastname = [employeeLevelDict optionalObjectForKey:@"lastname" defaultValue:[NSNull null]];
NSString *driverPhone = [employeeLevelDict optionalObjectForKey:@"phone" defaultValue:[NSNull null]];
NSString *driverId = [employeeLevelDict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
答案 1 :(得分:1)
在此尝试:
if( cabdriverLevelDict.allkeys.count ){
// Do something with the dict
} else {
// dict is empty
}
答案 2 :(得分:1)
基本上,您需要检查您获得的每一个结果。如果你不这样做,你的应用程序就会受到攻击,一次攻击可能会让黑客进入用户的设备并造成无限制的破坏。你期望一个字典,你可能会得到零,你可能得到一个null,你可能得到一个数字,或一个字符串,只是任何东西。这很简单。
NSDictionary* dict = ...;
if (! [dict isKindOfClass:[NSDictionary class]]) dict = nil;
在Objective-C中,nil对象非常安全。例如,你可以使用objectForKey [@“employee”],所有会发生的结果是你得到nil。你无论如何都可以收到零。
没有必要检查[NSNull null],因为服务器给你的任何其他结果都会使你的app崩溃。只需检查一下你的期望。抛弃不正确的数据很好,如果只有一个字节的数据错误,所有JSON反序列化器都会抛弃所有内容。
有时候你需要多做一些照顾,因为服务器行为不端,你必须应对它。例如,一个服务器应该返回一个字典数组,如果只有一个字典,可能只给你一个字典,所以你要检查例如
NSArray* arrayOfDicts = ...;
if ([arrayOfDicts isKindOfClass:[NSDictionary class]] arrayOfDicts = @[arrayOfDicts];
else if (! [arrayOfDicts isKindOfClass:[NSArray class]] arrayOfDicts = nil;
答案 3 :(得分:1)
正如其他人所指出的,如果传入字典的任何对象都是nil,那么会抛出一个崩溃你的应用程序的异常。通过执行以下操作:
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
您依赖于所有这些对象(例如time_service,id_service等)不是nil。正如您所指出的,它们可能是零,因此您需要有一种方法来检查您所做的每个对象。我建议使用一个NSMutableDictionary,使一个类别方法只添加键/值对,如果它们都不是nil:
@implementation NSMutableDictionary (Util)
-(void)setObjectOrRemoveIfNil:(id)anObject forKey:(id<NSCopying>)aKey
{
if (anObject == nil)
{
[self removeObjectForKey:aKey];
}
else
{
[self setObject:anObject forKey:aKey];
}
}
@end
然后把你的字典拼凑起来:
NSMutableDictionary* values = [NSMutableDictionary dictionary];
[values setObjectOrRemoveIfNil:time_service forKey:@"time_service"];
[values setObjectOrRemoveIfNil:id_service forKey:@"id_service"];
//Keep going with the rest of your values.
最后我们像你一样使用那个词典:
[historialServicios addObject:values];
答案 4 :(得分:0)
检查词典的计数
if ([cabdriverLevelDict count] == 0) {
NSLog("empty");
}
else{
// Do your stuff !!
}
答案 5 :(得分:0)
if (![cabdriverLevelDict isKindOfClass:[NSNull class]] ){
//do something
}
试试这个
答案 6 :(得分:-2)
你可以尝试
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
if (employeeLevelDict.count != 0)
{
// do something if dict is not empty
}
else
{
}];