2013-12-07 4 views
3

Я пытаюсь разобрать некоторые JSON из API, но у меня есть «проблема» подпараметров JSON. Мои методы делать это, похоже, могут быть красивее.Самый удобный способ разбора JSON в Objective-C?

Я пытаюсь разобрать из http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast?pretty и я получаю

{ 
    "result": "success", 
    "data": { 
     "last_local": { 
      "value": "785.00000", 
      "value_int": "78500000", 
      "display": "$785.00", 
      "display_short": "$785.00", 
      "currency": "USD" 
     }, 
     "last": { 
      "value": "785.00000", 
      "value_int": "78500000", 
      "display": "$785.00", 
      "display_short": "$785.00", 
      "currency": "USD" 
     }, 
     "last_orig": { 
      "value": "785.00000", 
      "value_int": "78500000", 
      "display": "$785.00", 
      "display_short": "$785.00", 
      "currency": "USD" 
     }, 
     "last_all": { 
      "value": "785.00000", 
      "value_int": "78500000", 
      "display": "$785.00", 
      "display_short": "$785.00", 
      "currency": "USD" 
     }, 
     "buy": { 
      "value": "785.00000", 
      "value_int": "78500000", 
      "display": "$785.00", 
      "display_short": "$785.00", 
      "currency": "USD" 
     }, 
     "sell": { 
      "value": "785.50000", 
      "value_int": "78550000", 
      "display": "$785.50", 
      "display_short": "$785.50", 
      "currency": "USD" 
     }, 
     "now": "1386421846023718" 
    } 
} 

Теперь я хочу, чтобы получить доступ к value в last на data. Мой способ сделать это гнездится кучу objectForKey: строки - такие, как

[[[[[self getInformationFrom:mtgox] objectForKey:@"data"] objectForKey:@"last"] objectForKey:@"value"] floatValue];

В основном то, что getInformationFrom:mtgox делает вернуть NSDictionary с NSJSONSerialization.

Есть ли лучший способ получить значение этих данных JSON?

ответ

6

Вы можете использовать dictionary literals:

[[self getInformationFrom:mtgox][@"data"][@"last"][@"value"] floatValue]; 

Или вы могли бы использовать KVC:

[[[self getInformationFrom:mtgox] valueForKeyPath:@"data.last.value"] floatValue]; 
+0

Это определенно красивее и читабельнее. Благодарю. – Filuren

+0

Существует также интерфейс, который позволяет вам указать список разделенных точками, но он хорошо скрыт в документации. –

+0

Да, это значениеForKeyPath в протоколе NSKeyValueCoding. –

2

JSON представляет собой протокол связи. Лучшее, что вы можете сделать, это сначала разобрать его на объекты.

Например, создайте класс MyPrice по методу initWithDictionary:. Этот класс будет читать все атрибуты value, currency.

Затем создать класс MyData которого initWithDictionary: прочтет last_all, buy атрибутов и делегировать разбор в -[MyPrice initWithDictionary].

Определить readonly свойства на классах.

Затем доступ к данным с использованием свойств, например. data.lastPrice.value.

Это больше работы, но это сделает ваш код намного красивее, потому что он будет работать с объектами, а не со словарями.

+0

+1. Это отличный пример работы, которая теперь приводит к меньшему количеству работы. Представьте себе другого человека, работающего над этим проектом. Предпочитают ли они читать 'data.lastPrice.value' или' [[[[[get_InformInformFrom: mtgox] objectForKey: @ "data"] objectForKey: @ "last"] objectForKey: @ "value"] floatValue]; ' ? Что-то столь же важное, как стоимость чего-то абсолютно заслуживает своего собственного Объекта. 'valueForKeyPath: @" data.last.value "' может быть причудливым, но это не то же самое, что Object. – Chris

+1

Это очень важный урок. Создание небольших классов данных сэкономит массу времени. В частности, это сэкономит вам много головной боли, когда вы поймете, что никогда не должны управлять валютой в качестве плавающего (небольшие ошибки округления всегда будут преследовать вас). Когда вы осознаете, что вам нужно управлять им как валютным объектом с помощью «NSDecimalNumber», вы будете очень рады, что у вас есть класс на месте и не просто раздавали поплавки. (Пример этого см. На странице https://github.com/iosptl/ios6ptl/blob/master/ch17/Money/Money/RNMoney.h) –

+0

@RobNapier Я работаю в компании, которая занимается ценообразованием. Я могу только согласиться. Другим решением является работа с денежными суммами в виде целых чисел, но это очень часто приводит к переполнениям. – Sulthan

Смежные вопросы