NSXMLParser initWithContentsOfURL - 解析GZIP的响应

时间:2011-10-13 05:40:37

标签: ios macos nsxmlparser

我有一个iOS应用程序正在调用某些XML数据的Web服务:

NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser setShouldResolveExternalEntities:NO];        
[xmlParser parse];

我一直收到错误:

Error parsing XML: The operation couldn’t be completed. 
(NSXMLParserErrorDomain error 31.)

错误31是“NSXMLParserUnknownEncodingError”。我在WireShark中嗅到了HTTP响应,结果发现Web服务正在发送带有GZIP数据的“Content-Encoding:gzip”,并且这样做的原因是因为从iOS发送的请求设置了“Accept-Encoding” :gzip,deflate“在HTTP标头中。似乎initWithContentsOfURL告诉web服务器,它实际上不能处理gzip数据。

我猜我需要将Web服务器响应加载到NSData中,然后通过解压缩器方法运行它以获取NSString,然后将该字符串传递给NSXMLParser。

我的问题是,这种减压的最佳方法是什么? zlib的?从iOS中链接到ZLib的任何问题?

谢谢你,
有状态

P.S。我也用osx标记了这个,因为我想这个问题也会存在,因为NSXMLParser是一个基础类。

2 个答案:

答案 0 :(得分:1)

使用NSURLConnection委托方法从webservice下载响应。然后将数据传递给NSXMLParser initWithContentsOfData。 通过使用NSURLConnection委托方法(异步连接),您不会阻止当前线程。这是下载响应的推荐方法。加上NSURLConnection解压缩(缩小)g-zip压缩响应。你不需要做任何特别的事情来放气。 您可以在将数据提供给NSXMLParser(感谢Steven)之前检查数据。

使用NSXMLParser initWithContentsOfURL应主要用于解析应用程序中的XML文件(在资源或文档部分中)。它肯定会与你的web服务连接以下载响应但它等同于同步调用并阻塞你的线程。 避免使用NSURLConnection sendSynchronous和initWithContentsOfURL来传递远程Web服务URL。

答案 1 :(得分:0)

NSURLConnection自动处理gzip解压缩(即下载)。 iOS特别要求HTTP标头中的gzip内容。它可以处理它。

同步网络事务是一个问题。相反,您应该使用异步请求来获取数据。数据完成后,您可以将其传递给NSXMLParser。另一个好处是你将能够检查数据,你可能会发现它不是真正的XML。

作为快速查看正在发生的事情,我相信有一种NSData方法可以同步从URL下载。然后可以将该数据实例提供给NSXMLParser。但这是临时修复。您不希望在应用程序中保留任何同步网络;如果它需要太长时间,看门狗会杀死你的应用程序死。但它可能会指出你的XML出了什么问题。