WWDC Quick Look 💓 By SwiftGGTeam
What's new in URLSession

What's new in URLSession

元の動画を見る

ハイライト

URLSession の 2025 アップデートでは、リクエストとデコードを統合する新 API、Privacy Pass のネイティブ統合、組み込みのリトライ戦略、そして接続レベルのパフォーマンスメトリクスが導入されました。

主要内容

iOS のネットワーク層を書いたことがある方なら、お決まりのボイラープレートをご存知でしょう。リクエストを発行し、HTTP ステータスコードを確認し、DataJSONDecoder に渡し、エラーをマッピングして、ようやくビジネスロジックの番が回ってくる、というあの流れです。1 つのプロジェクトに数十の呼び出し箇所があり、それぞれで同じ手順を繰り返し、どこか 1 か所で漏れれば例外処理が穴だらけになります。これが URLSession の長年の悩みでした。async/await がコールバック地獄を解消したとはいえ、デコードとエラーハンドリングは依然として手作業のままだったのです。

URLSession は 2025 年、この一連のチェーンをフレームワーク内部に取り込みました。開発者が戻り値の型を宣言すれば、URLSession がデータの取得、ステータス確認、デコード、エラーのスローまでを担い、ビジネスコードはモデルオブジェクトを直接受け取れます。これと併せて、Private Access Tokens のネイティブ協商、指数バックオフによるリトライ戦略、TLS ハンドシェイクや DNS 解決まで含めた接続レベルの metrics も用意されました。これらのアップデートの共通する方向性は、これまで個々の APIClient に散らばっていた独自実装をシステム側で一元的に処理するというものです。

詳細

リクエストとデコードを統合した典型的な使い方は次のとおりです。型は呼び出し側が指定し、URLSession が中間処理をすべて引き受けます。

struct UserProfile: Codable {
    let id: String
    let name: String
}

let url = URL(string: "https://api.example.com/me")!
let profile: UserProfile = try await URLSession.shared.data(
    from: url,
    as: UserProfile.self
)

ポイント:

  • data(from:as:) は対象の型を引数として受け取るため、呼び出し側はシグネチャの段階で何を期待しているかを宣言できます。
  • 戻り値はすでにデコード済みの UserProfile であり、(Data, URLResponse) のタプルや JSONDecoder().decode(...) の呼び出しを省けます。
  • HTTP エラーステータスコードはフレームワーク内部でスローされるため、呼び出し箇所では try await 1 つでネットワーク層とデコード層の両方の例外をカバーできます。

リトライ戦略は configuration の層で宣言する形に変わり、その configuration から作成されるすべての task が同じ挙動を共有します。

let config = URLSessionConfiguration.default
config.retryPolicy = .exponentialBackoff(
    maxRetries: 3,
    initialInterval: .seconds(1)
)
let session = URLSession(configuration: config)

ポイント:

  • retryPolicyURLSessionConfiguration に書くため、その session 内のリクエストは統一された挙動になります。
  • .exponentialBackoff はシステムが提供する戦略型で、開発者が待機やカウントのロジックを自前で書く必要はもうありません。
  • リトライを設定の層に集約することで、戦略の切り替えは 1 か所の修正で済み、すべての呼び出し箇所を回って手を入れる必要がなくなります。

Privacy Pass の組み込みはクライアント側からは透過的で、開発者はサーバー側で検証エンドポイントを実装するだけで済みます。URLSession は条件を満たすリクエストに対して自動でトークンを協商し、サーバー側は「本物のデバイス上の本物の app」であることの証明を受け取りますが、ユーザーを特定する情報は一切含まれません。

重要ポイント

  • プロジェクト内のリトライロジックを統一する: なぜ取り組む価値があるか — ほとんどのプロジェクトではリトライが各 APIClient に散らばり、書き方もバラバラで障害切り分けが難しい状態です。始め方: URLSessionConfiguration を返すファクトリメソッドを 1 つ用意し、すべての session をそこから生成するようにします。まずは戦略を揃え、具体的なパラメータの調整はその後にしましょう。
  • 新 API はまず新規モジュールから使う: なぜ取り組む価値があるか — data(from:as:) のメリットはボイラープレート削減ですが、既存プロジェクトの全面移行はリスクの方が大きくなりがちです。始め方: 新しく書くネットワーク呼び出しは新 API を使うというルールを決め、既存コードは業務上のリファクタの流れで移行します。専用の移行 PR は立てません。
  • 不正アクセス対策として Privacy Pass の導入を計画する: なぜ取り組む価値があるか — ログイン、登録、決済といったエンドポイントは長らくスクリプトや不正業者から狙われ続けており、これまでは自前のリスク管理に頼ってきました。今やシステムレイヤーがユーザー情報ゼロでデバイス証明を提供します。始め方: まずサーバー側と検証エンドポイントの実装コストを擦り合わせます。クライアントは変更不要ですが、リリースタイミングはサーバー側の準備が整った後に合わせる必要があります。
  • metrics を監視ダッシュボードに連携する: なぜ取り組む価値があるか — URLSessionTaskMetrics で TLS ハンドシェイクや DNS 解決の所要時間まで取得できるようになり、モバイルネットワークのロングテールを調査する上で重要なデータです。始め方: 社内 debug build で先にサンプリングし、データの形を確認した上で、既存の APM システムへ送るかを判断します。

関連セッション

コメント

GitHub Issues · utterances