Shared session vs. session with default configuration

最近遇到一個問題,就是透過 NSURLSession 的 NSURLSessionDataTask 送 post 到第二台 server ,某種特定的架構下(例如連proxy 或 tunnel),會讓第二台 server 完全連不上。

What are the differences between the two session objects created in these two different ways:

NSURLSession *session = [NSURLSession sharedSession];


NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

As you’re using them, they’re functionally very similar. But using sharedSession doesn’t give you the ability to customize the NSURLSessionConfiguration (e.g. tweak the cache, custom headers, etc.) nor use the delegate-based rendition of NSURLSession.

說明:一般的情況下使用 sharedSession 應該就ok, 問題是出問題之後,請改用 NSURLSessionConfiguration.


session with basic set of properties that control various policies on a sessionwide basis. These properties are set on a session at the time of its creation and cannot be changed later. If you need to change these policy properties, create a new session with a modified session configuration.


Returns a shared singleton session object.

Please review Apple Documents first as these are the source of very information.

所以,每次都去 create new session 可以避免某些問題!

使用 proxy 的範例如下:

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 = @"";
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:@""]];

// 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];

如果直接使用上面的 code 可能會遇到這一個 warning:

Sending 'ViewController *const __strong' to parameter of incompatible type 'id<NSURLSessionDelegate> _Nullable'


Confirm <NSURLSessionDelegate> in your header file and it will solve the issue i think,

  @interface ViewController : UIViewController <NSURLSessionDataDelegate>

It is because you are setting delegate to self in NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; So it’s requires to confirm NSURLSessionDataDelegate protocol.




你的電子郵件位址並不會被公開。 必要欄位標記為 *