ios - 分块解析 XML 文件,无需等待 Swift 中的完整下载

标签 ios xml swift swift3

在 iOS 中,我想在下载时从服务器解析 XML 流。它不应该等到服务器完成构建 XML 和下载完成。服务器以“ block ”的形式构建 XML 并将其直接发送给客户端。在我的应用程序中,我有一个 UITableView,它应该在我从服务器收到 XML 元素后立即显示它。

我已经尝试使用 XMLParser(contentsOf: URL) 构造函数,但这首先会下载整个 XML,然后对其进行解析。还有另一个构造函数 XMLParser(stream: InputStream),但我不知道如何从 URLConnection 获取 InputStream。我唯一找到的是 this question这已经快 5 岁了,我不明白如何在 Swift 3 中做到这一点,如果它能工作的话。

我尝试的另一件事是通过 Libxml2,但我在 RAM 使用或其他方面遇到了问题(请参阅我的 old question)。

如何在 Swift 中不必等待完整下载而分 block 解析 XML 流?

在 Android 中,我会使用 XMLPullParser 并且:

URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
InputStream inputStream = connection.getInputStream();

XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = xmlFactoryObject.newPullParser();
pullParser.setInput(inputStream, null);
// here comes the actual parsing

最佳答案

基本上有两种类型的解析器:SAX 和 DOM。根据您的要求,您在收到 XML 元素后立即更新 UITableView,很明显您将不得不仅使用 SAX 解析器。 (DOM 解析器解析了整个文档并构建了一个内存中表示,您可以查询不同的元素)。

下面列出了两种流行的 iOS SAX 解析器:

1)NSXMLParser(已重命名为 XMLParser)- 默认包含在 iPhone SDK 中。

2)libxml2 - 是一个开源库,默认包含在 iPhone SDK 中

苹果做出了出色的code名为 XMLPerformance 的示例允许您比较使用 NSXML 和 libxml2 API 解析包含前 300 首 iTunes 歌曲的 ~900KB XML 文档所需的时间。

好的,这是一张显示解析器内存使用峰值的图表(这是通过对象分配工具运行各种方法获得的)

a busy cat

数据清楚地表明,就内存使用峰值而言,libxml2 的 SAX 方法(您已经尝试过)是最佳选择。

另一方面,实现 XMLParser 非常容易。下面是我尝试使用它的示例片段。

在类声明中,实现 XMLParserDelegate 协议(protocol)

class ViewController: UIViewController,XMLParserDelegate {

override func viewDidLoad() {
    super.viewDidLoad()

使用下面的方法来初始化解析器:

func xmlParser()
{
    posts = []
    parser = XMLParser(contentsOf:(NSURL(string:"http://images.apple.com/main/rss/hotnews/hotnews.rss"))! as URL)!
    parser.delegate = self
    parser.parse()
}

初始化委托(delegate)后,将在需要时调用以下委托(delegate)方法:

func parserDidStartDocument(_ parser: XMLParser) {
    print("started")
}

func parserDidEndDocument(_ parser: XMLParser) {
    print("ended")
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    print("didEndElement")
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    print("foundCharacters")
}

还有其他委托(delegate)方法,您可以根据需要调用。

关于ios - 分块解析 XML 文件,无需等待 Swift 中的完整下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41974608/

相关文章:

xml - 打开两个XMl文件时Visual Studio崩溃

ios - 符合符合 NSObjectProtocol 的协议(protocol),而不从 NSObject 继承?

快速迁移 : Argument labels '(_:)' do not match any available overloads

ios - 如果由于网络连接不良而尚未完成创建,如何删除 CKRecord?

ios - 使用iOS版Google Maps API无法获取当前位置坐标

sql-server - XEvents 的死锁图不会生成 "good"XML

c++ - iOS中Opencv人脸检测Cascade编译器报错

java - XMLStreamReader 和一个真正的流

ios - 为 iOS 13 SDK 构建的 Phonegap

ios - 关于过渡/动画的奇怪 Safari 行为