【问题标题】:Prettiest way to parse JSON in Objective-C?在 Objective-C 中解析 JSON 的最漂亮方法?
【发布时间】: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 数据的价值?

【问题讨论】:

    标签: ios objective-c json macos


    【解决方案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 我在一家从事定价业务的公司工作。我只能同意。将金额作为整数处理是另一种解决方案,但它通常会导致溢出。
    猜你喜欢
    • 2019-08-03
    • 2011-04-29
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多