在 Objective-C 中解析 JSON 的最漂亮方法?

Posted

技术标签:

【中文标题】在 Objective-C 中解析 JSON 的最漂亮方法?【英文标题】:Prettiest way to parse JSON in Objective-C? 【发布时间】:2013-12-07 14:20:33 【问题描述】:

我正在尝试从 API 解析一些 JSON,但我在解析 JSON 的子元素时遇到了“麻烦”。我这样做的方法似乎更漂亮。

我正在尝试从 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@lastdata。我这样做的方法是嵌套一堆 objectForKey:string——比如

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

基本上getInformationFrom:mtgox 所做的是返回一个带有 NSJSONSerialization 的 NSDictionary。

有没有更好的方法来获取这个 JSON 数据的价值?

【问题讨论】:

【参考方案1】:

你可以使用dictionary literals:

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

或者你可以使用KVC:

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

【讨论】:

还有一个接口可以让你指定一个点分隔的列表,但是在文档中隐藏的很好。 对,就是NSKeyValueCoding协议中的valueForKeyPath。【参考方案2】:

JSON 是一种通信协议。你能做的最好的事情就是先把它解析成对象。

例如,使用方法initWithDictionary: 创建一个类MyPrice。该类将读取所有valuecurrency 属性。

然后创建一个类MyData,其initWithDictionary: 将读取last_allbuy 属性并将解析委托给-[MyPrice initWithDictionary]

在类上定义readonly 属性。

然后使用属性访问数据,例如data.lastPrice.value.

这需要更多的工作,但它会让你的代码更漂亮,因为它可以处理对象,而不是字典。

【讨论】:

+1。这是一个很好的例子,现在更多的工作导致以后的工作更少。想象一下从事这个项目的其他人。他们更喜欢阅读data.lastPrice.value,还是[[[[[self getInformationFrom:mtgox] objectForKey:@"data"] objectForKey:@"last"] objectForKey:@"value"] floatValue];?与某物的成本一样重要的东西绝对值得拥有自己的对象。 valueForKeyPath:@"data.last.value" 可能很花哨,但它与 Object 不同。 这是非常重要的一课。创建小型数据类可以在以后节省大量麻烦。特别是,当您意识到您永远不应该将货币作为浮动来管理时,它会为您省去很多麻烦(小的舍入错误总是会困扰您)。当您意识到您需要使用NSDecimalNumber 将其作为货币对象进行管理时,您会很高兴您有一个适当的课程,而不仅仅是在处理浮动。 (有关此示例,请参阅github.com/iosptl/ios6ptl/blob/master/ch17/Money/Money/…) @RobNapier 我在一家从事定价业务的公司工作。我只能同意。将金额作为整数处理是另一种解决方案,但它通常会导致溢出。

以上是关于在 Objective-C 中解析 JSON 的最漂亮方法?的主要内容,如果未能解决你的问题,请参考以下文章

在objective-c中有效解析单元素JSON

在 IOS(Objective-C)中有效地解析 JSON 到 Realm DB

如何在 Objective-C iOS 中解析 JSON

在 Objective-C 中解析 JSON 后的随机结果

在 Objective-C 中解析 JSON 数组

Json在objective-c中解析nil字段