iOS - Use AFNetworking with custom NSURLProtocol class

So, for other looking for information about this:

Along with the fact that AFURLSessionManager doesn't use the standard NSURLProtocol registrations, it also processes the array First-In-First-Out, not Last-In-First-Out like NSURLProtocol.

Meaning, if you want to overwrite the behavior of the AFURLSessionManager (say for testing purposes), you can't just add your NSURLProtocol subclass to session.configuration.protocolClasses, you must instead add it to the beginning of the array (or at least in front of the behavior you're overwriting/modifying).


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

@ryanwa was partially correct that you need to insert the new protocol at the start of the array, but it still won't work because the configuration can't be changed after the NSURLSession is made. 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'm aware you don't need to register your NSURLProtocol subclass with registerClass. This worked for me on iOS 9.1 on an 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 mutable values within the configuration object has no effect on the current session, but you can create a new session with the modified configuration object.