[WWDC18] iOS 12で登場するNetwork Frameworkでネットワークプログラミングが容易になりそうです #WWDC18

iOS 12で登場するNetwork Frameworkの紹介と、Connectionの確立方法およびデータ送信のサンプルをご紹介します。
2018.06.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本記事は Apple からベータ版として公開されているドキュメントを情報源としています。 そのため、正式版と異なる情報になる可能性があります。ご留意の上、お読みください。

Network Framework とは

Network FrameworkはiOS 12で追加される、トランスポート・セキュリティプロトコルを使用したデータ送受信を行うためのフレームワークです。

Network Framework を使うケース

TLS、TCP、UDPや独自のアプリケーションプロトコルに直接アクセスする必要がある場合に使用します。HTTP(S)やURLベースのリソースの読み込みの場合はこれまでと変わらずURLSessionを使用しますが、URLSession自体も内部でNetwork Frameworkを使用しています。

Network Frameworkが登場した背景

これまでのSocketプログラミングは以下のようなものでした。

  • getaddrinfoなどのC言語のAPIを使う必要がある
  • 接続を確立するための手順も多く、Socketプログラミング自体が比較的難しかった

Network Frameworkは上記のような問題を解決し、ネットワークプログラミングを容易にするために登場しました。

Connectionのセットアップ

Connectionをセットアップする手順は以下の通りです。

  1. NWEndpointNWParametersを使用してconnectionを生成する
  2. connection.start()を呼ぶ
  3. connectionが.ready状態になるのを待つ

以下はメール送信のためのConnectionをセットアップするサンプルです。

let connection = NWConnection(host: "mail.example.com",
                              port: .imaps,
                              using: .tls)

connection.stateUpdateHandler = { state in
    switch state {
    case .ready:
        // データ送受信が可能な状態
    case .waiting(let error):
        ()
        // 有効なネットワークがない等の理由で接続が確立できない
    case .failed(let error):
        // 接続が切れた
        ()
    case .setup:
        // 初期状態
        ()
    case .cancelled:
        // クライアントによりキャンセルされ、接続が無効になった
        ()
    case .preparing:
        // 接続準備中
        ()
    }
}

let queue = DispatchQueue(label: "label")
connection.start(queue: queue)

Connectionの状態は6種類ある

Connectionの状態は以下の6種類あります。.readyがデータを送受信できる状態です。

/// States a connection may be in
public enum State : Equatable {

    /// The initial state prior to start
    case setup

    /// Waiting connections have not yet been started, or do not have a viable network
    case waiting(NWError)

    /// Preparing connections are actively establishing the connection
    case preparing

    /// Ready connections can send and receive data
    case ready

    /// Failed connections are disconnected and can no longer send or receive data
    case failed(NWError)

    /// Cancelled connections have been invalidated by the client and will send no more events
    case cancelled
}

ready状態になったらデータを送受信する

connectionを確立して状態が.readyになったらデータを送受信します。送信結果はクロージャーで受け取ります。

以下は任意のデータを送信するサンプルです。

switch state {
case .ready:
    // データ送受信が可能な状態
    let someData = Data()
        connection.send(content: someData,
                        completion: .contentProcessed({ error in
                            if let error = error {
                                // エラー
                            } else {
                                // 送信成功
                            }
                        }))

最後に

本記事ではNetwork Frameworkの紹介と、Connectionの確立方法およびデータ送信のサンプルをご紹介しました。 これまでのSocketプログラミングに比べかなりとっつきやすくなった印象です。 サンプルなので実装していませんが、connectionのエラーやキャンセルはちゃんとハンドリングするようにしましょう。

細かいオプションも多数あるので詳細は公式ドキュメントをご覧ください。

参考