概要
URLSessionオブジェクトを再利用することによる通信処理の効率化について記載します。
障害事象
弊社が開発しているiOSアプリのデータ転送量が多すぎるのではないかという報告を受けました。データ転送量を測定してみると、HTTPリクエスト・レスポンスのヘッダーおよびボディサイズの合計の2.5倍程度の量が発生していました。
※このアプリの外部への通信はすべてSwift標準のHTTPRequestを使用して実装されています。
調査方法
XCodeのDebug Navigatorで通信状況を調べてみることにしました。
- シミュレーターでアプリを起動
- ツールバー > [View] > [Navigators] > [Debug] を選択
- [Network] をクリック
以下のgifアニーメーションがそのときの状況です。[Active Connections]のところを見ると、TCPコネクションが短時間のうちに発生したり消えたりしていることが分かりました。このことから、TCPコネクションが再利用されていないことが問題であると推測されました。
問題点と修正内容
通信処理の実装では、APIエンドポイントごとのタイムアウト値を設定するためHTTPSession.shared
は使用しておらず、リクエストの度にURLSessionオブジェクトを生成していました。
// 修正前のコード
func getXXX(...) {
let config = URLSession.shared.configuration
config.timeoutIntervalForRequest = 5
config.timeoutIntervalForResource = 10
let session = URLSession(configuration: config)
urlSession.dataTask(with: request) { ... }
}
以下のようにURLSessionをstaticプロパティに保持して、再利用するように修正しました。
// 修正後のコード
static let urlSessionForXXX: URLSession = {
let config = URLSessionConfiguration.ephemeral
config.timeoutIntervalForRequest = 5
config.timeoutIntervalForResource = 10
return URLSession(configuration: config)
}()
func getXXX(...) {
urlSessionForXXX.dataTask(with: request) { ... }
}
修正後の効果
以下のgifアニーメーションが修正後の状況です。[Active Connections]のところを見ると、TCPコネクションが存在し続けていることが分かります。
また、データ転送量の合計は以前の半分程度に減りました。