最近遇到一個問題,就是透過 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.
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 = @"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.