简体   繁体   English

如何在iOS中动态解析JSON

[英]How to parse JSON dynamically in iOS

We used a third party service and it provides a JS file. 我们使用了第三方服务,它提供了一个JS文件。 The js file launches an http request and get a json.We parsed the json and got the content we wanted but the json format always changes. js文件启动一个http请求并获取一个json。我们解析了json并得到了我们想要的内容,但是json格式总是在变化。

Is there a way to parse the json but do not update our app? 有没有办法解析json但不更新我们的应用程序?

It sounds awful stupid to constantly change schemas, but anyway, maybe you could try having a manifest somewhere in the cloud that translates the latest schema keywords into one your app understands? 不断更改架构听起来很愚蠢,但是无论如何,也许您可​​以尝试在云中某处找到清单,将最新的架构关键字转换为您的应用可以理解的清单?

Basically, I presume that the info in the JSON is similar (otherwise it wouldn't make sense at all) and only the keywords change. 基本上,我认为JSON中的信息是相似的(否则根本就没有意义),只有关键字会发生变化。 You could have a JSON you constantly update that translates the keywords used in the app into the newest one used by the webservice. 您可能会拥有不断更新的JSON,它将应用程序中使用的关键字转换为Web服务使用的最新关键字。

So an example would look like this. 因此,示例如下所示。 Imagine this is the format you are used to when developing the app (this is the one app expects). 想象一下,这是开发应用程序时惯用的格式(这是一个应用程序期望的格式)。

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

Now if the webservice changes it's schema and returns something like this 现在,如果Web服务更改了它的架构并返回了类似的内容

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

You should have a manifest.json which translates it like this 您应该有一个manifest.json像这样翻译它

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

I hope you get where I'm going with this, basically you can shift the translation to the cloud, giving you the chance to keep it up to date while app remains the same. 我希望您能按此方向进行操作,基本上,您可以将翻译转移到云中,让您有机会在应用保持不变的情况下保持最新。 So after loading in the translation you can access the data like this 因此,在加载翻译后,您可以像这样访问数据

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

The JSON home page has quite a bit of materials on the subject which should allow you to develop your own parser if you wish. JSON主页上有很多关于该主题的资料,如果您愿意,应该可以让您开发自己的解析器。 There are also some ObjectiveC parsers available down at the bottom of the page. 页面底部还有一些ObjectiveC解析器。

http://www.json.org/ http://www.json.org/

For this purpose we looked at Cocoa's standard key path infrastructure but weren't particularly happy with how it combines with arrays and dictionaries. 为此,我们研究了Cocoa的标准关键路径基础结构,但对将其与数组和字典结合使用并不特别满意。 In the end I ended up writing my own little key-path lookup thing, essentially like: 最后,我最终编写了自己的小关键路径查找内容,基本上是这样的:

- (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];
             }
    }
}

So you might call objectAtPath:@"shoes.4.typeOfLaces" inObject:jsonResult if 'jsonResult' is a dictionary to get the array 'shoes', the dictionary at index 4 in the array and then whatever value that dictionary has for the key 'typeOfLaces'. 因此,如果“ jsonResult”是用于获取数组“ shoes”的字典,该数组中索引4的字典以及该字典对该键具有的任何值,则可以在objectAtPath:@"shoes.4.typeOfLaces" inObject:jsonResult调用objectAtPath:@"shoes.4.typeOfLaces" inObject:jsonResult 'typeOfLaces'。

The production code actually has some smarter navigation aids, allowing you to say things like "take whichever object in this array of dictionaries has the largest value for the key 'size'" or "take the object with type=large if it exists, otherwise take any object", but exactly what you want to do there will depend on your app and the variability of the schema. 生产代码实际上具有一些更智能的导航辅助,使您可以说出诸如“获取此字典数组中具有键'size'的最大值的任何对象”之类的东西,或者“如果存在则使用type = large的对象,否则,接受任何对象”,但是您要在该对象中执行的操作完全取决于您的应用和架构的可变性。

Once you're navigating object graphs by key path, you can just grab the current key paths from a server somewhere, allowing you to change how JSON is navigated on device without submitting a new binary. 通过键路径导航对象图后,您只需从某处的服务器获取当前键路径,即可更改JSON在设备上的导航方式,而无需提交新的二进制文件。

The only warning I'd add is to be careful how much functionality you put into your key paths. 我要添加的唯一警告是要小心您在关键路径中添加了多少功能。 Apple don't allow fresh code to be downloaded so whatever you do you don't want to end up at anything that Apple could construe as a scripting language, no matter how restricted. Apple不允许下载新鲜的代码,因此无论您受到什么限制,无论您做什么,Apple都不会以Apple可以将其解释为脚本语言的任何方式结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM