Мне нужно было знать имена ключей для значений, поэтому я переписал то, что имел Джоэл, и придумал это:
- (void)enumerateJSONToFindKeys:(id)object forKeyNamed:(NSString *)keyName
{
if ([object isKindOfClass:[NSDictionary class]])
{
// If it's a dictionary, enumerate it and pass in each key value to check
[object enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
[self enumerateJSONToFindKeys:value forKeyNamed:key];
}];
}
else if ([object isKindOfClass:[NSArray class]])
{
// If it's an array, pass in the objects of the array to check
[object enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self enumerateJSONToFindKeys:obj forKeyNamed:nil];
}];
}
else
{
// If we got here (i.e. it's not a dictionary or array) so its a key/value that we needed
NSLog(@"We found key %@ with value %@", keyName, object);
}
}
И тогда вы бы назвали это так:
[self enumerateJSONToFindKeys:JSON forKeyNamed:nil];
В качестве альтернативы, если вы хотите сделать данный путь ключа изменяемым (чтобы вы могли выполнить обратную запись, используя setValue:forKeyPath:
), вы можете сделать что-то вроде следующего:
- (void)makeDictionariesMutableForKeyPath:(NSString *)keyPath {
NSArray *keys = [keyPath componentsSeparatedByString:@"."];
NSString *currentKeyPath = nil;
for (NSString *key in keys) {
if (currentKeyPath) {
NSString *nextKeyPathAddition = [NSString stringWithFormat:@".%@", key];
currentKeyPath = [currentKeyPath stringByAppendingString:nextKeyPathAddition];
} else {
currentKeyPath = key;
}
id value = [self.mutableDictionary valueForKeyPath:currentKeyPath];
if ([value isKindOfClass:NSDictionary.class]) {
NSMutableDictionary *mutableCopy = [(NSDictionary *)value mutableCopy];
[self.mutableDictionary setValue:mutableCopy forKeyPath:currentKeyPath];
}
}
}