iOS – использование AFNetworking с пользовательским классом NSURLProtocol

У меня есть пользовательский класс NSURLProtocol, который я реализовал с помощью этого руководства . Мои реализации практически такие же, как в учебнике, помимо имен, модели данных и т. Д.

По сути, я пытаюсь отправить HTTP-запрос, но вместо URL-адреса, начинающегося с: «http: //», он должен начинаться с, скажем: «bla: //»

Теперь я пытаюсь зарегистрировать класс протокола и использовать его через фреймворк AFNetworking, и у меня возникают проблемы.

Метод canInitWithRequest: начинает возвращать НЕТ в какой-то момент, и в этот момент запрос терпит неудачу, и я продолжаю получать ошибку «неподдерживаемого URL».

Помимо регистрации класса протокола, я попытался добавить класс в AFHTTPSessionManager , вызвав его в методе didFinishLaunchingWithOptions :

 [NSURLProtocol registerClass:[MyURLProtocol class]]; NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:[AFHTTPSessionManager manager].session.configuration.protocolClasses]; [protocolsArray addObject:[MyURLProtocol class]]; [AFHTTPSessionManager manager].session.configuration.protocolClasses = [protocolsArray copy]; 

И я также добавил схему URL-адресов в поле URL-схемы в файле info.plist приложения

Еще не повезло … Я пытаюсь сделать то, что я могу сделать? И если да, то чего я могу потерять? благодаря

Итак, для других, ищущих информацию об этом:

Наряду с тем фактом, что AFURLSessionManager не использует стандартные регистрации NSURLProtocol , он также обрабатывает массив First-In-First-Out, а не Last-In-First-Out, такой как NSURLProtocol .

Если вы хотите переписать поведение AFURLSessionManager (скажем, для целей тестирования), вы не можете просто добавить свой подкласс NSURLProtocol к session.configuration.protocolClasses , вы должны вместо этого добавить его в начало массива (или, по крайней мере, перед поведением, которое вы переписываете / изменяете).

Итак, во-первых, @dopcn прав, что вам нужно сохранить свой экземпляр AFHTTPSessionManager .

@ryanwa был частично прав, что вам нужно вставить новый протокол в начале массива, но он все равно не будет работать, потому что конфигурация не может быть изменена после создания NSURLSession . Правильное решение – использовать initWithSessionConfiguration :

 NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSMutableArray * protocolsArray = [sessionConfiguration.protocolClasses mutableCopy]; [protocolsArray insertObject:[MyURLProtocol class] atIndex:0]; sessionConfiguration.protocolClasses = protocolsArray; AFHTTPSessionManager * myManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:sessionConfiguration]; //retain this somewhere! 

Насколько мне известно, вам не нужно регистрировать свой подкласс NSURLProtocol с помощью registerClass . Это работало для меня на iOS 9.1 на iPad Mini 4.

Из документов на NSURLSession :

@property(readonly, copy) NSURLSessionConfiguration *configuration

Описание

Копия объекта конфигурации для этого сеанса. (только для чтения) Изменение изменяемых значений в объекте конфигурации не влияет на текущий сеанс, но вы можете создать новый сеанс с измененным объектом конфигурации.

Привет [AFHTTPSessionManager manager] не возвращает объект singleton, а возвращает новый экземпляр. Поэтому, если вы просто установите protocolClasses в didFinishLaunchingWithOptions для одного экземпляра AFHTTPSessionManager но используете другой экземпляр, созданный [AFHTTPSessionManager manager] другом месте, новый менеджер не имеет вашего настраиваемого класса протокола. Это может привести к проблемам.

Interesting Posts
Давайте будем гением компьютера.