关于具有多个连接/提要/视图的 XML 解析的设计/实现建议

发布于 2024-12-12 06:24:01 字数 1091 浏览 0 评论 0 原文

开始我的第一个 iOS 项目,并希望获得有关如何构建应用程序的建议。 该应用程序提取 XML 提要,对其进行解析并显示表示 XML 提要中的项目的列表。单击列表中的某个项目时,应用程序将使用之前拉取的 XML feed 中的属性之一拉取新的 XML feed。这种情况会发生多个拉取、解析、显示层,并且在用户选择时再次执行相同的操作。现在大多数 XML 元素结构都是这样的:(

这些是简单的示例,只是为了演示正在发生的事情)

返回(在新视图上显示信息):

<items>
    <item id="123" name="item 1" />
    <item id="124" name="item 2" />
    <item id="125" name="item 3" />
</itmes>

返回:

<itemDescription>
    <description itemId="123" name="desc 1" description="blah 1" />
</itemDescription>

想知道:

  • 我应该在每个视图中拥有连接类/对象还是新连接?
  • 我应该有一个解析器类/对象还是解析每个视图中的 XML 提要?
  • 我还希望存储一些返回的数据,因此如果用户导航回主项目列表,我不需要再次调用 XML 提要,但我每次都需要解析 itemsDescription XML 提要。

我已经看过一些关于解析 XML 的教程,并且了解了如何执行此操作的要点,希望更多地关注设计和可重用性,而不是在每个新视图中重复代码。或者我对它的工作原理还很遥远

Starting my first iOS project and wanted to advice on how to structure the application.
The app pulls a XML feed, parses it out and displays a list representing the items in the XML feed. When clicking on a item in the list the app will pull a new XML feed using one of the attributes from the previously pulled XML feed. This happens several layers of pull, parse, display and on user selection do the same thing over again. Now most of the XML element structure is something like this:

(These are simple examples just to demonstrate what's going on)

returns (Display info on new view):

<items>
    <item id="123" name="item 1" />
    <item id="124" name="item 2" />
    <item id="125" name="item 3" />
</itmes>

returns:

<itemDescription>
    <description itemId="123" name="desc 1" description="blah 1" />
</itemDescription>

Wanted to know:

  • Should I have a connection class/object or a new connection in each view?
  • Should I have a parser class/object or parse the XML feed in each view?
  • I'm also looking to store some of the data returned so I don't need to call the XML feed again if the user navigates back to the main items list, but I would need to parse the itemsDescription XML feed every time.

I've looked at several tutorials on parsing XML and I get the gist of how to do this, wanting to focus more of the design and reusability instead of duplicating the code over in each new view. Or am I way off on how this works

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦幻之岛 2024-12-19 06:24:01

遵循Apple指南执行此操作的最佳方法是检查他们的示例之一,几个月前我按照此示例制作了一个与您的应用程序类似的应用程序。您还可以了解如何使您的应用程序处于离线模式。

基本结构(无离线模式):

SeismicXML 示例应用程序演示了如何使用 NSXMLParser
解析 XML 数据。当您启动应用程序时,它会下载并
解析来自美国地质调查局 (USGS) 的 RSS 提要
它提供了世界各地最近发生的地震的数据。它显示
每次地震的位置、日期和震级,以及
指示地震严重程度的颜色编码图形。这
XML 解析使用 NSOperation 在后台线程上进行,
使用批量解析的对象更新地震表视图。

高级结构(离线模式):

演示如何在多线程环境中使用 Core Data,
遵循核心数据中提到的第一个推荐模式
编程指南。

基于 SeismicXML 示例,它下载并解析 RSS 提要
来自美国地质调查局 (USGS) 提供的数据
最近世界各地发生地震。这个样本有何不同
是它使用核心数据持久存储地震。每次
您启动该应用程序,它会下载新的地震数据,并以
NSOperation 检查重复项并存储新创建的
地震作为管理对象。

对于那些刚接触 Core Data 的人来说,比较 SeismicXML 会很有帮助
用这个样品进行取样,并注意必要的成分
在您的应用程序中引入核心数据。

关于 cwieland 答案,我不会使用 ASIHTTPRequest 因为 过时,所以如果你想遵循他的方法,我建议你使用 AFNetworking ,您可以在其中轻松快速地处理 XML 请求:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.flickr.com/services/rest/?method=flickr.groups.browse&api_key=b6300e17ad3c506e706cb0072175d047&cat_id=34427469792%40N01&format=rest"]];
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
  XMLParser.delegate = self;
  [XMLParser parse];
} failure:nil];

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];

The best way you can do this following Apple Guidelines is checking one of their examples, some months ago I made an app similar to yours following this example. Also you can see how to make your app in offline mode.

Basic structure (w/o offline mode):

The SeismicXML sample application demonstrates how to use NSXMLParser
to parse XML data. When you launch the application it downloads and
parses an RSS feed from the United States Geological Survey (USGS)
that provides data on recent earthquakes around the world. It displays
the location, date, and magnitude of each earthquake, along with a
color-coded graphic that indicates the severity of the earthquake. The
XML parsing occurs on a background thread using NSOperation and
updates the earthquakes table view with batches of parsed objects.

Advanced structure (with offline mode):

Demonstrates how to use Core Data in a multi-threaded environment,
following the first recommended pattern mentioned in the Core Data
Programming Guide.

Based on the SeismicXML sample, it downloads and parses an RSS feed
from the United States Geological Survey (USGS) that provides data on
recent earthquakes around the world. What makes this sample different
is that it persistently stores earthquakes using Core Data. Each time
you launch the app, it downloads new earthquake data, parses it in an
NSOperation which checks for duplicates and stores newly founded
earthquakes as managed objects.

For those new to Core Data, it can be helpful to compare SeismicXML
sample with this sample and notice the necessary ingredients to
introduce Core Data in your application.

Regarding cwieland answer I wouldn't use ASIHTTPRequest because is outdated, so if you want to follow his approach I would recomend you to use AFNetworking, where you can handle an XML request easy and fast:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.flickr.com/services/rest/?method=flickr.groups.browse&api_key=b6300e17ad3c506e706cb0072175d047&cat_id=34427469792%40N01&format=rest"]];
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
  XMLParser.delegate = self;
  [XMLParser parse];
} failure:nil];

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];
江城子 2024-12-19 06:24:01

这是我将如何实现它。我会将 ASIHTTPRequest 用于所有连接项,而不用担心这一部分。它可以使用简单的委托方法轻松处理所有异步数据下载。

我将有一个解析器类,它接受 url,异步下载它,然后解析返回的数据。然后,它会通过委托方法将已解析子项​​的数组返回到表视图,该表视图将在 xml 数据中显示子项。

我将创建一个 UITableViewController 的子类,它将处理任何 url/数据类型,在这种情况下,您只需编写一个表视图类,而不必担心用户如何导航。这将使您只需要编写一个类,它就可以处理任意数量的向下钻取或组合。此实现在很大程度上取决于 xml 数据的不同级别的复杂程度。如果它们截然不同,那么在表格视图中使用更清晰的代码而不是在单元格创建中对数据类型进行 if 检查会更有意义。

使用导航样式应用程序将消除每次从堆栈中弹出视图时加载视图时重新解析数据的需要。任何时候,虽然它都会重新解析,但 urls-> 数组的简单缓存可以解决这个问题(如果需要/想要的话)。不过,每次应用程序启动时都需要重新加载数据。当然,如果您收到 3 级深度的内存警告,则需要在备份时重新解析或缓存检索。

如果你想要一个缓存系统,我会编写一个类,它位于视图控制器和检查存储的 url 解析器之间,如果它在其中,则返回数据数组,否则返回 nil 并获取它。

我个人会使用 NSXMLParser,因为这是我熟悉的。您可能希望将元素存放在类包装器中,在这种情况下,您只需检查 didStartElement 上的元素类型,并设置一个枚举以通过创建来打开。使用 nsxmlparser 这非常容易。我没有使用任何其他解析器进行比较,但确实发现调试 NSXMLParser 非常简单,编码也很简单,因此启动并运行它并不难。这是一个关于所有不同 xml 解析器的很棒的网站:

http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

所以总而言之,我会一个NSObject 的子类接受 url,通过 ASIHTTPRequest 下载它,解析它。 UITableviewController 的子类,在单元格点击时它会使用新的 url 分配相同的视图控制器类并将其推送到导航堆栈上。该视图将显示加载屏幕,直到返回数组,然后重新加载数据。希望这将是一个非常干的吻。

我会在全局类中放置尽可能多的代码。如果每次提取的数据只有一个主要类别,例如

<items>
    <stuff></stuff>
    ....
    <stuff></stuff>
</items>
EOF

我将使用一个数组来容纳所有值,如果有多个主要部分,我会将所有内容存储在一个字典中,其中父属性作为键和值在一个数组中。然后在表视图上根据字典的键有不同的部分。

我希望这能回答您的一些问题。我不确定你要找的级别有多低。我是通过开发相当多的应用程序和编写 RSS 阅读器来发言的。如果您需要我澄清任何内容,请告诉我。

Here is how I would implement it. I would use ASIHTTPRequest for all connection items and not worry about that part of it. It can handle all of your downloading of data asynchronous very easily with simple delegate methods.

I would have a parser class that takes in the url, downloads it asynchronously, and then parses the data returned. It would then return the array of parsed children through a delegate method to a tableview that would display the children in the xml data.

I would create a subclass of UITableViewController that will handle any url/data type in which case you'd only have to write up one tableview class and not worry about how the user navigates through. This would make it so that you only need to write one class and it would handle any number of drill downs or combinations. This implementation depends heavily on how complicated the distinct levels of xml data is. If they are drastically different it would make more sense to have cleaner code in the tableview and not have if's checking on the type of data in the cell creation.

Using a navigation style app would eliminate the need to re-parse the data each time the view loads as you pop views off the stack. Anytime going forward though it would be re-parsing but a simple cache of the urls->array could solve this if needed/wanted. It would require the reloading of the data each time the app launches though. Of course if you received a memory warning 3 levels deep it would require a re-parse or cache retrieval on your way back up.

If you are wanting a caching system I would write a class that goes in-between the view controllers and the url parser that checks the store and if it is in there return the array of data otherwise return nil and go get it.

I personally would use NSXMLParser as that is what I'm familiar with. You may want to house the elements in a class wrapper in which case you would just have to check which type of element you have on didStartElement and set an enum to switch on through creation. that is pretty easy with nsxmlparser. I haven't used any other parser to compare with but did find that debugging NSXMLParser was simple enough and coding was straightforward so it wasn't to hard to get it up and running. Here is a great site on all the different xml parsers:

http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

So in summary I would have a subclass of NSObject that accepts the url, downloads it through ASIHTTPRequest, parses it. A Sublcass of UITableviewController that on the cell tap it allocates the same view controller class with the new url and pushes it on the navigation stack. The view would show a loading screen until the array is returned and then just reload the data. It would be a very DRY KISS hopefully.

I would house as much of the code in global classes as possible. If each pull of data there is only one main category, as in

<items>
    <stuff></stuff>
    ....
    <stuff></stuff>
</items>
EOF

I would use an array to house all the values, If there is more than one main section I would store everything in a dictionary with the parent attribute as the key and the values in an array. Then on the tableview have different sections based on the keys of the dictionaries.

I hope this answers some of your questions. I'm not sure how low of level you were looking for. I speak from developing quite a few apps and writing a RSS reader. Let me know if there is anything you'd like me to clarify.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文