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

and

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.


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.

sharedSession

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

如果直接使用上面的 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.

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *