Reputation: 1045
I am trying to set my text
string to a URL. The following code works, but I feel like I can refactor it to make it look neater.
NSString *text = @“”;
id json = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
if ([json isKindOfClass:[NSDictionary class]]) {
id data = json[@“data”];
if ([data isKindOfClass:[NSDictionary class]]) {
id value = data[@"value"];
if ([value isKindOfClass:[NSArray class]]) {
id url = [value valueForKey:@"url"];
if ([url isKindOfClass:[NSString class]]) {
text = url;
}
}
}
}
So far it has the whole "mountain of doom" going on and I want to know how can I check if the object type is correct without using so many if statements. Any tips or suggestions are appreciated.
Edit: This is the lite version of my code, but the concept is the same.
Upvotes: 0
Views: 69
Reputation: 12144
In my opinion, there are 2 ways to make it look neater and ignore if-else-nesting-hell.
Using return
.
NSString *text = @“”;
id json = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
if (![json isKindOfClass:[NSDictionary class]]) {
return;
}
id data = json[@“data”];
if (![data isKindOfClass:[NSDictionary class]]) {
return;
}
id value = data[@"value"];
if (![value isKindOfClass:[NSArray class]]) {
return;
}
id url = [value valueForKey:@"url"];
if (![url isKindOfClass:[NSString class]]) {
return;
}
text = url;
Create a generic method which checks kind of class and return a safe value
- (id)safeValueFromObject:(id)object forKey:(NSString *)key class:(Class)valueClass {
if (![object respondsToSelector:@selector(valueForKey:)]) {
return [[valueClass alloc] init];
}
id result = [object valueForKey:key];
return [result isKindOfClass:valueClass] ? result : [[valueClass alloc] init];
}
Use
NSString *text = @"";
id json = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
id data = [self safeValueFromObject:json forKey:@"data" class:NSDictionary.class];
id value = [self safeValueFromObject:data forKey:@"value" class:NSArray.class];
id url = [self safeValueFromObject:value forKey:@"url" class:NSString.class];
text = url;
Upvotes: 3