iOS NSURLCache создает HTTP 404 при прохождении через NSURLProtocol

Если вы серьезно относитесь к ответу на этот вопрос, пожалуйста, клонируйте созданное мной мини-приложение и посмотрите, не ведет ли оно себя так же, прежде чем размышлять над ответом, спасибо :)

https://github.com/pavel-zdenek/nsurlprotocol-testbed

Очень простой браузер: UIWebView все запросы проходят через простую NSURLProtocol повторную реализацию. По истечении времени загрузки. Переключатель отменяет регистрацию обработчика протокола во время выполнения. Теперь загрузите один конкретный сайт: http://www.rollingstone.com. Помимо множества других ресурсов, страница ПОЛУЧАЕТ

http://sjc.ads.nexage.com/js/admax/admax_api.js

который производит запрос XHR для

_ 4_

PZProtocolHandler ВЫКЛ: XHR загружается мгновенно. Наблюдается как HTTP 200 на проводе (акула), отображается как успешная загрузка в Safari Web Inspector. При дальнейших загрузках он больше не в сети, но по-прежнему HTTP 200 в Web Inspector. Другими словами, кешированный.

PZProtocolHandler ВКЛ: Web Inspector сообщает о 3 попытках, время ожидания каждой из которых составляет 10 секунд, в результате получается HTTP 404. Никаких изменений при дальнейших перезагрузках. Теперь самое интересное: согласно проводам (акуле), запрос выходит и получает ответ правильным HTTP 200. Кроме того, все 3 попытки упорядочиваются по одному и тому же каналу TCP. «Кто-то» - это составляя 404 по пути к UIWebView.

Теперь, еще до чтения умных блогов, я обнаружил, что iOS Кеширование URL-адресов происходит термоядерно, когда ответ сервера не содержит заголовка Cache-Control. И этот GET-запрос именно такой. Но это не должно приводить к сбою 404, не так ли? Также я попытался перевести в спящий режим кэширование по умолчанию с помощью различных методов: реализация связанных с кешированием вызовов делегатов в NSURLProtocol, создание нового запроса с флагами, запрещающими кеширование, с использованием ожидаемых высших знаний в SDURLCache, даже заменив NSURLCache тем, что, как я думаю, должно быть "нулевым кешем". Смотрите все в исходниках проекта.

404-й остается для меня. Я сомневаюсь, что простой факт отмены NSURLProtocol так сильно сломал бы ситуацию. Я мог бы жить без возможности заполнить радар за это, спасибо. Я все еще надеюсь, что делаю что-то не так.


person Pavel Zdenek    schedule 08.09.2014    source источник
comment
У меня такая же проблема с NSURLSession   -  person Mrug    schedule 16.06.2017


Ответы (1)


Проблема не совсем решена, скорее сузилась и немного прояснилась. Если возникнет новый вопрос, он, скорее всего, будет совсем другим, поэтому я отвечаю на него самостоятельно.

Так что это вероятно не проблема кеша. Сайт загружается нормально, если явно задано NSOperationQueue:

_connection = [[NSURLConnection alloc] initWithRequest:request
                                            delegate:self
                                    startImmediately:NO];
// comment out for sure stalling
[_connection setDelegateQueue:[NSOperationQueue mainQueue]];
[_connection start];

Я бы хотел предпочесть currentQueue, но это nil в момент [NSURLProtocol startLoading]. Какой согласно документу Apple должно означать, что startLoading не является NSOperation, следовательно, очереди нет.

Явная маршрутизация к основному потоку, очевидно, создает другое узкое место в производительности: вызовы делегатов останавливаются, когда пользовательский интерфейс взаимодействует с пользовательским интерфейсом, наиболее типичным примером является попытка прокрутки частично загруженной страницы. Хотя это тоже проблема, я могу наполнить Apple TSI чем-то особенным. Все новые знания будут отправлены в репозиторий github.

ОБНОВИТЬ:

Теперь проблема полностью решена, если сделать еще одну простую вещь: создать новую ванильную NSOperationQueue и установить для нее очередь NSURLConnectionDelegate:

[_connection setDelegateQueue:_theNewlyCreatedQueue];

Вы не увидите этого ни в одном из многочисленных NSURLProtocol советов в Интернете. Было бы излишне самоуверенно утверждать, что я знаю, почему это так сильно улучшает ситуацию, но теперь проблемный веб-сайт загружается почти так же плавно, как в Mobile Safari (в пределах ожидаемой разницы в скорости выполнения JavaScript), поэтому проблема решена для меня.

person Pavel Zdenek    schedule 10.09.2014
comment
Я столкнулся с той же проблемой и использовал NSURLSession stackoverflow.com/ questions / 44584159 / - person Mrug; 16.06.2017