Jeff Jeff - 6 months ago 64
iOS Question

How to programmatically add a proxy to an NSURLSession

Looking over the documentation of

NSURLSession
and
NSURLSessionConfiguration
, I was under the impression I should configure it with a dictionary like the following:

// Create a dictionary to describe the proxy
NSDictionary *proxyDict = @{
(NSString *)kCFProxyHostNameKey : @"myProxyHost.com",
(NSString *)kCFProxyPortNumberKey : @"12345",
(NSString *)kCFProxyTypeKey : (NSString*)kCFProxyTypeHTTP
};

// Create a configuration that uses the dictionary
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
[configuration setConnectionProxyDictionary:proxyDict];


However, the requests from
NSURLSession
created with this configuration connect directly.

Answer

It turns out, the dictionary keys you want are the Stream variants, they are the ones that resolve down to "HTTPProxy" and such:

NSString* proxyHost = @"myProxyHost.com";
NSNumber* proxyPort = [NSNumber numberWithInt: 12345];

// Create an NSURLSessionConfiguration that uses the proxy
NSDictionary *proxyDict = @{
    @"HTTPEnable"  : [NSNumber numberWithInt:1],
    (NSString *)kCFStreamPropertyHTTPProxyHost  : proxyHost,
    (NSString *)kCFStreamPropertyHTTPProxyPort  : proxyPort,

    @"HTTPSEnable" : [NSNumber numberWithInt:1],
    (NSString *)kCFStreamPropertyHTTPSProxyHost : proxyHost,
    (NSString *)kCFStreamPropertyHTTPSProxyPort : proxyPort,
};

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
configuration.connectionProxyDictionary = proxyDict;

// Create a NSURLSession with our proxy aware configuration
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

// Form the request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com?2"]];

// Dispatch the request on our custom configured session
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:
                              ^(NSData *data, NSURLResponse *response, NSError *error) {
                                  NSLog(@"NSURLSession got the response [%@]", response);
                                  NSLog(@"NSURLSession got the data [%@]", data);
                              }];

NSLog(@"Lets fire up the task!");
[task resume];