Есть ли лучший способ разобрать этот JSON, кроме того, который я уже использую? - PullRequest
0 голосов
/ 19 мая 2011

Недавно у меня была возможность получить данные почтового индекса из API Карт Google. В конце этого вопроса я включил большой фрагмент строки ответа JSON, которую я получаю от Google.

Глубоко в своем коде я получаю ответ и анализирую его, используя библиотеку TouchJSON от Джонатана Уайта. Это мой код

NSStringEncoding encoding;

// Fetch data from web service.
NSString *jsonString = [NSString stringWithContentsOfURL:url usedEncoding:&encoding error:nil];
// Process JSON data returned from web service.
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];

if (jsonString == nil)
{
// bah
} else if (![self isCancelled]) {// Check to see if we have been cancelled.

    if (dictionary) {
        NSArray* results = [dictionary objectForKey:@"results"];
        NSDictionary* types = [results objectAtIndex:1];
        NSArray* address_components = [types objectForKey:@"address_components"];
        NSDictionary* postcodes = [address_components objectAtIndex:0];
        NSString* postcode = [postcodes objectForKey:@"long_name"];
    // do stuff with the postcode
    }
//
}

Обратите внимание, как я получаю словарь типов и словарь почтовых индексов, используя определенное смещение в NSArray. Мой вопрос действительно такой,

Как можно проанализировать строку JSON (желательно с помощью TouchJSON) без необходимости жесткого кодирования этих смещений массива?

Меня удивляет, что строка ответа Google Maps может быть изменена, и мой жестко закодированный подход перестанет работать в этот момент. Кто-нибудь там использовал подобный, но более надежный подход, который он бы тоже хотел здесь поделиться?

... Пример строки ответа API Карт Google ... Почтовый индекс 'target' выделен жирным шрифтом

{"status": "OK", "results": [{ "types": ["street_address"], "formatted_address": "9 Clarendon Pl, Leamington Spa, Уорикшир CV32 5, Великобритания", "address_components": [{ "long_name": "9", "short_name": "9", "types": ["street_number"] }, { "long_name": "Clarendon Pl", "short_name": "A452", "types": ["route"] }, { "long_name": "Лимингтон Спа", "short_name": "Лимингтон Спа", "types": ["locality", "политические"] }, { "long_name": "Warwick", "short_name": "Warwick", "types": ["administrator_area_level_3", "политический"] }, { "long_name": "Уорикшир", "short_name": "Warks", "types": ["administrator_area_level_2", "политический"] }, { "длинное имя": "Англия", "short_name": "Англия", "types": ["administrator_area_level_1", "политический"] }, { "длинное_имение": "Великобритания", "short_name": "GB", "types": ["country", "политические"] }, { "long_name": "CV32 5", "short_name": "CV32 5", "types": ["postal_code_prefix", "postal_code"] }], "геометрия": { "место нахождения": { "lat": 52,2919849, "lng": -1.5399505 }, "location_type": "RANGE_INTERPOLATED", "viewport": { "юго-запад": { "lat": 52,2888374, "lng": -1.5431216 }, "к северо-востоку": { "lat": 52,2951326, "lng": -1.5368264 } }, "границы": { "юго-запад": { "lat": 52,2918320, "lng": -1.5399760 }, "к северо-востоку": { "lat": 52.2921380, "lng": -1.5399720 } } }}, { "types": ["postal_code"], "formatted_address": "Лимингтон Спа, Уорикшир CV32 5LD, Великобритания", "address_components": [{ "длинное_имя": "CV32 5LD" , "short_name": "CV32 5LD", "types": ["postal_code"] }, { "long_name": "Лимингтон Спа", "short_name": "Лимингтон Спа", "types": ["locality", "политические"] }, ......... намного больше JSON следует

1 Ответ

2 голосов
/ 20 мая 2011

Я никогда не использовал TouchJSON , но мне кажется, что ваши жестко заданные смещения присутствуют, потому что вы ожидаете только один результат, но API Карт Google достаточно гибок, чтобы возвращать несколько результатов.На самом деле, если у вас есть objectAtIndex:1, это означает, что вы берете второй набор результатов, поэтому написанный вами код фактически зависит от наличия как минимум двух результатов.

Даже если я получилподробности не так, я подозреваю, что вы действительно хотите сделать вместо NSDictionary* types = [results objectAtIndex:1]; что-то вроде:

NSDictionary* types = [results objectAtIndex:[results indexOfObjectPassingTest:yourPredicateHere]];

Если вы не знаете, как работают предикаты, вы захотите прочитать Программирование предикатов AppleСначала объясните, как установить предикат (то, что я пометил yourPredicateHere выше).http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/predicates.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...