在 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 文档所需的时间。
好的,这是一张显示解析器内存使用峰值的图表(这是通过对象分配工具运行各种方法获得的)
数据清楚地表明,就内存使用峰值而言,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/