NSXMLParser initWithContentsOfURL - анализ GZIP-ответа - PullRequest
0 голосов
/ 13 октября 2011

У меня есть приложение для iOS, которое вызывает веб-сервис для некоторых XML-данных, например:

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».Я прослушал HTTP-ответ в WireShark, и оказалось, что веб-служба отправляет «Content-Encoding: gzip» с данными GZIP в теле, и причина, по которой он это делает, заключается в том, что запрос, отправляемый с iOS, устанавливает «Accept-Encoding»: gzip, deflate "в заголовках HTTP.Кажется, initWithContentsOfURL сообщает веб-серверам, что он может обрабатывать данные gzip, когда на самом деле это не так.

Я предполагаю, что мне нужно загрузить ответ веб-сервера в NSData, затем запустить его через метод декомпрессора, чтобы получить строку NSString, а затем передать эту строку в NSXMLParser.

У меня вопрос,какой лучший способ сделать эту декомпрессию?ZLib?Есть ли какие-либо проблемы со связью с ZLib из iOS?

Спасибо,
Stateful

PS Я пометил это также с помощью osx, так как я думаю, что эта проблема также будет присутствовать, поскольку NSXMLParser являетсяБазовый класс.

Ответы [ 2 ]

1 голос
/ 13 октября 2011

Используйте методы делегата NSURLConnection для загрузки ответа от веб-службы. затем передайте данные в NSXMLParser initWithContentsOfData. Используя методы делегата NSURLConnection (асинхронное соединение), вы не блокируете текущий поток. Это рекомендуемый способ загрузки ответа. Плюс NSURLConnection распаковывает (выкачивает) сжатый ответ g-zip. Вам не нужно делать ничего особенного, чтобы спустить это. И вы можете проверить данные, прежде чем передать их NSXMLParser (Спасибо, Стивен).

Использование NSXMLParser initWithContentsOfURL следует в основном использовать для анализа XML-файлов в вашем приложении (в разделах ресурсов или документов). Он обязательно устанавливает соединение с вашим веб-сервисом для загрузки ответа, НО это эквивалентно синхронному вызову и блокирует ваш поток Избегайте NSURLConnection sendSynchronous и initWithContentsOfURL для передачи URL удаленного веб-сервиса.

0 голосов
/ 13 октября 2011

NSURLConnection обрабатывает распаковку gzip (т.е. загрузку) автоматически.iOS специально запрашивает содержимое gzip в заголовке HTTP.Он может справиться с этим.

Однако синхронная сетевая транзакция является проблемой.Вместо этого вы должны использовать асинхронный запрос для получения данных.Когда данные закончены, вы можете передать их на NSXMLParser.Еще одним преимуществом этого является то, что вы сможете просматривать данные, которые, вероятно, обнаружат, что это не совсем XML.

Как быстрый взлом, чтобы увидеть, что происходит, я считаю, что есть NSData метод загрузки с URL-адреса синхронно.Затем этот экземпляр данных может быть передан в NSXMLParser.Но это временное исправление.Вы не хотите оставлять какие-либо синхронные сети в своем приложении;если это займет слишком много времени, сторожевой таймер убьет ваше приложение мертвым.Но он, вероятно, укажет, что не так с вашим XML.

...