Objective-C
OSX
iOS
Cocoa

NSURLSessionで任意のProxyを使う

More than 3 years have passed since last update.


はじめに

OS X MavericksとiOS7で、NSURLSessionが追加されました。

NSURLSessionを使った通信では、何も指定しなければ、従来のNSURLConnectionと同様、システムで設定されているプロキシを使って通信することになります。

ところが、NSURLSessionはNSURLConnectionとは違い、任意のプロキシを使う方法があります。

ここでは、NSURLSessionでシステムの設定に関係なく任意のプロキシを使ったり、あるいはプロキシを使わないようにしたりする方法を見ていきます。

ちなみに、NSURLSessionは機能が豊富ですが、今回の件であまり関係のない部分はかなり省略します。


NSURLSessionConfiguration

NSURLSessionを使用する際には、NSURLSessionConfigurationオブジェクトを作って渡してやる必要があります。

HTTP通信に最低限必要なコードは次のようになると思います。


基本的な通信の例

NSURL *url = [NSURL URLWithString:@"http://example.com/"];

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
/* dataを使った処理 */
}];
[dataTask resume];


実はこのNSURLSessionConfigurationに、プロキシを設定するためのプロパティがあります。それがconnectionProxyDictionaryです。詳しく見ていきましょう。


プロキシを指定するには

プロキシに関する値を設定したNSDictionaryオブジェクトを、NSURLSessionConfigurationのconnectionProxyDictionaryプロパティに設定します。

プロキシが localhost:8080 にあると仮定して、このプロキシを通して通信したいときは、次のようなコードを上記のサンプルコードのconfigを作成した後に追加します。(各自の環境にあわせて読み替えてください。)

config.connectionProxyDictionary = @{(NSString *)kCFStreamPropertyHTTPProxyHost: @"localhost",

(NSString *)kCFStreamPropertyHTTPProxyPort: @8080,
(NSString *)kCFNetworkProxiesHTTPEnable: @YES};

kCFStreamPropertyHTTPProxyHostでHTTPプロキシのホストを、kCFStreamPropertyHTTPProxyPortでHTTPプロキシのポートを、kCFNetworkProxiesHTTPEnableでHTTPプロキシを使うかどうかを指定しています。


プロキシを使わないように指定するには

逆に、システムに設定されているプロキシに関係なく、プロキシを使わずに通信したいときは、kCFNetworkProxiesHTTPEnableの値をNOにします。

config.connectionProxyDictionary = @{(NSString *)kCFNetworkProxiesHTTPEnable: @NO};


もっと詳しく

リファレンスを引くと、 CFProxySupport Reference というページがあります。このページの Global Proxy Settings Constants に設定ディクショナリのキー値の一覧があるので、詳しくはこちらをご覧ください。HTTP以外にもプロキシの設定項目があります。PACファイルを使ったプロキシの自動設定にも対応しているようです。

ちなみに、定義されているキー値の型がCFStringRefになっているので、上記の例ではNSString *にキャストしています。