IOS - using AFNetworking with a custom class NSURLProtocol

I have my own class NSURLProtocol which I implemented using this guide . My implementations are almost the same as in the tutorial, with the exception of names, data models, etc.

Essentially, I'm trying to send an HTTP request, but instead of a URL starting with: "http: //", it should start with, say, "bla: //"

Now I'm trying to register a protocol class and use it through the AFNetworking framework , and I'm having some problems.

canInitWithRequest: method starts returning NO at some point, and at that moment the request is not executed, and I continue to receive an "unsupported URL" error.

In addition to registering the protocol class , I tried to add the class to the AFHTTPSessionManager protocolClasses by calling this in the didFinishLaunchingWithOptions method:

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

And I also added a URL scheme to the URL scheme field in the info.plist application.

Still out of luck ... Is it possible that I'm trying to do? And if so, what could I miss? thanks

+6
source share
3 answers

So, for others, looking for information about this:

AFURLSessionManager does not use standard NSURLProtocol registrations, it also processes the First-In-First-Out array, not the Last-In-First-Out NSURLProtocol , like NSURLProtocol .

Meaning, if you want to overwrite the behavior of AFURLSessionManager (say, for testing purposes), you cannot just add your subclass NSURLProtocol to session.configuration.protocolClasses , you should instead add it to the beginning of the array (or at least before the behavior, which you rewrite / modify).

+5
source

So, firstly, @dopcn is right that you need to save your AFHTTPSessionManager instance.

@ryanwa was partially correct that you need to insert a new protocol at the beginning of the array, but it still won’t work, because the configuration cannot be changed after creating the NSURLSession . The correct solution is to use 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! 

As far as I know, you do not need to register a subclass of NSURLProtocol with registerClass . This worked for me on iOS 9.1 on the iPad Mini 4.

From the docs on NSURLSession :

@property(readonly, copy) NSURLSessionConfiguration *configuration

Description

A copy of the configuration object for this session. (read-only) Changing the mutable values ​​in the configuration object does not affect the current session, but you can create a new session with the modified configuration object.

+2
source

Hello [AFHTTPSessionManager manager] does not return a singleton object, but returns a new instance. Therefore, if you simply set protocolClasses to didFinishLaunchingWithOptions for one instance of AFHTTPSessionManager , but use another instance created by the [AFHTTPSessionManager manager] in another place, the new manager does not have the protocol class you registered. This can lead to problems.

-1
source

Source: https://habr.com/ru/post/981541/


All Articles