Is it possible to change defaultSessionConfiguration of NSURLSessionConfiguration?

90 views Asked by At

I have an ios app. I want to modify defaultSessionConfiguration so that every time later in the code when I call [NSURLSessionConfiguration defaultSessionConfiguration] I will get my modified defaultSessionConfiguration

I tried something like this but it didn't work

NSURLSessionConfiguration *configuration = NSURLSessionConfiguration.defaultSessionConfiguration;
// Set the proxy configuration options in the connectionProxyDictionary property
NSDictionary *proxyDict = @{
    @"HTTPSEnable": [NSNumber numberWithInt:1],
    @"HTTPSProxy": @"localhost",
    @"HTTPSPort": [NSNumber numberWithInt:1234]
};
configuration.connectionProxyDictionary = proxyDict;

This one gives me a configuration with an empty connectionProxyDictionary

NSURLSessionConfiguration *configuration2 = [NSURLSessionConfiguration  defaultSessionConfiguration];

There is a lib in my app that makes requests to some host. I know that this lib uses NSURLSessionConfiguration defaultSessionConfiguration. I want to modify the "global" defaultSessionConfiguration so that the lib would start sending requests through my proxy.

1

There are 1 answers

0
dgatwood On

The only thing you can really do would be to swizzle the method (and I can't be 100% certain that you won't run into class cluster weirdness that might prevent doing that).

At a high level, you'd do something like this:

  • Create a method implementation (IMP) using imp_implementationWithBlock. IIRC, its parameters should be:
    • The object that is being operated on
    • The method parameters in order
  • Look up the method with class_getInstanceMethod.
  • Replace the implementation of that method using method_setImplementation.
  • Store the result of that method (the previous IMP) in a static global variable.
  • Cast the IMP to a function pointer. IIRC, the arguments the function pointer should be:
    • The object that is being operated on
    • The selector for the method (@selector(defaultSessionConfiguration))
    • The method parameters in order
  • Call that function pointer from the custom implementation block, then modify the results before returning them.

Be sure to do all of this in a dispatch_once block, e.g.

- (void)load {
  static dispatch_once_t once;
  static id sharedInstance;
  dispatch_once(&once, ^{
    // Code goes here...
  });
}

to ensure that you cannot do this more than once.

Note, however, that this is fairly risky to do in a production app. It is better, whenever possible, to ask the framework developer to provide hooks for passing in a session of your own creation (or a configuration of your own creation).

Documentation links: