【问题标题】:How to parse JSON dynamically in iOS如何在 iOS 中动态解析 JSON
【发布时间】:2012-01-01 07:06:34
【问题描述】:

我们使用了第三方服务,它提供了一个 JS 文件。 js文件发起http请求,得到一个json。我们解析了json,得到了我们想要的内容,但是json格式总是在变化。

有没有办法解析 json 但不更新我们的应用程序?

【问题讨论】:

  • 您是说 JSON 数据的第 3 方提供商一直在更改其架构?因为解决这个问题的唯一方法是相应地重建和更新您的应用程序。不过,我无法想象什么样的服务会即时更改架构。

标签: javascript objective-c ios json api


【解决方案1】:

不断更改架构听起来非常愚蠢,但无论如何,也许您可​​以尝试在云中的某个地方创建一个清单,将最新的架构关键字转换为您的应用可以理解的关键字?

基本上,我认为 JSON 中的信息是相似的(否则根本没有意义),只有关键字发生了变化。您可以拥有一个不断更新的 JSON,将应用中使用的关键字转换为 Web 服务使用的最新关键字。

所以一个例子看起来像这样。想象一下,这是您在开发应用程序时习惯的格式(这是应用程序所期望的)。

{
    "name" : "Henri",
    "title" : "iOS Developer"
}

现在,如果 web 服务更改了它的架构并返回类似这样的内容

{
    "key1" : "Henri",
    "key2" : "iOS Developer"
}

你应该有一个 manifest.json 像这样翻译它

{
    "name" : "key1",
    "title" : "key2"
}

我希望你能明白我的意思,基本上你可以将翻译转移到云端,让你有机会在应用保持不变的同时保持最新状态。因此,在加载翻译后,您可以像这样访问数据

NSString *name = [actualJSON objectForKey: [manifestJSON objectForKey: @"name"]];

【讨论】:

  • +1 这很聪明。我同意不断更改架构听起来非常复杂 - 尽管我想我缺乏架构更改原因的上下文。
【解决方案2】:

JSON 主页上有很多关于该主题的材料,如果您愿意,应该可以让您开发自己的解析器。页面底部还有一些可用的 ObjectiveC 解析器。

http://www.json.org/

【讨论】:

  • 我们可以解析json文件,但是json的格式总是变化的!这就是重点。
【解决方案3】:

为此,我们查看了 Cocoa 的标准 key path 基础架构,但对它与数组和字典的结合方式并不特别满意。最后我写了自己的小键路径查找,基本上就像:

- (id)objectAtPath:(NSString *)path inObject:(id)object
{
    // accept an input string like key1.key2.key3.index.key4.etc;
    // so we'll split on the dots and use each separate component
    // to navigate the object graph
    NSString *components = [path componentsSeparatedByString:@"."];
    for(NSString *component in components)
    {
         if([object isKindOfClass:[NSDictionary class]])
         {
             // if this is a dictionary, use this component as
             // a key into the dictionary
             object = [object objectForKey:component];
         }
         else
             if([object isKindOfClass:[NSArray class]])
             {
                 // if this is an array, use this component
                 // as an index into the array
                 NSInteger index = [component integerValue];

                 // treat out of bounds indices as finding nil
                 // rather than raising an exception
                 if(index < 0 || index >= [object count]) object = nil;
                 else object = [object objectAtIndex:index];
             }
    }
}

因此,如果 'jsonResult' 是一个字典,则可以调用 objectAtPath:@"shoes.4.typeOfLaces" inObject:jsonResult 来获取数组 'shoes'、数组中索引 4 处的字典以及该字典对键 'typeOfLaces' 的任何值。

生产代码实际上有一些更智能的导航帮助,允许您说诸如“取这个字典数组中的任何一个对象,该对象的键 'size' 具有最大值”或“取 type=large 的对象,如果它存在,否则取任何对象”,但您想要在那里做什么将取决于您的应用程序和架构的可变性。

一旦您通过关键路径导航对象图,您可以从某处的服务器获取当前关键路径,从而允许您更改 JSON 在设备上的导航方式,而无需提交新的二进制文件。

我要添加的唯一警告是要小心您在关键路径中添加了多少功能。 Apple 不允许下载新代码,因此无论您做什么,您都不希望以任何 Apple 可以解释为脚本语言的方式结束,无论多么受限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2021-04-08
    • 2020-04-17
    相关资源
    最近更新 更多