Swift Academy · レッスン

カスタムPublisherとSubscriber

独自のCombineコンポーネントを構築します。

レッスン 4/413 ステップ

「カスタムPublisherとSubscriber」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

組み込み Publisher の先へ

Combine には多くの Publisher が用意されていますが、Combine 以外の API を Publisher としてラップしたり、バックプレッシャーを細かく制御しながら値を受け取ったりする必要が生じることもあります。その場合は、Publisher と Subscriber のプロトコルを自分で実装します。

Publisher プロトコル

Publisher は Output 型と Failure 型を宣言し、receive(subscriber:) を実装します。このメソッドで、接続してきた Subscriber に Subscription を渡します。

protocol Publisher {
    associatedtype Output
    associatedtype Failure: Error
    func receive<S: Subscriber>(subscriber: S)
        where S.Input == Output, S.Failure == Failure
}

Subscription の役割

Subscriber が接続すると、Publisher は Subscription オブジェクトを作成します。Subscription は、要求量を管理しながら値を配信するための接続役です。Subscription に準拠し、Cancellable を継承します。

カスタム Subscription

Subscription は Subscriber を保持し、要求に応じて値を送信します。

final class CountSubscription<S: Subscriber>: Subscription
    where S.Input == Int {
    private var subscriber: S?
    private var current = 0

    init(subscriber: S) {
        self.subscriber = subscriber
    }

    func request(_ demand: Subscribers.Demand) {
        var remaining = demand
        while remaining > 0 {
            remaining -= 1
            remaining += subscriber?.receive(current) ?? .none
            current += 1
        }
    }

    func cancel() {
        subscriber = nil
    }
}

カスタム Publisher

Publisher は Subscription を作成し、receive(subscription:) を通じて Subscriber に渡すだけです。

struct CountPublisher: Publisher {
    typealias Output = Int
    typealias Failure = Never

    func receive<S: Subscriber>(subscriber: S)
        where S.Input == Int, S.Failure == Never {
        let subscription = CountSubscription(subscriber: subscriber)
        subscriber.receive(subscription: subscription)
    }
}

Demand を理解する

バックプレッシャーは Combine のフロー制御です。Subscriber は特定の Demand を要求し、Publisher は要求された数を超える値を送信してはなりません。receive(_:) から要求量を返すと、許容量が増えます。

Subscriber プロトコル

カスタム Subscriber は3つのメソッドを実装します。まず Subscription を受け取り、次に各値を受け取り、最後に完了を受け取ります。

protocol Subscriber {
    associatedtype Input
    associatedtype Failure: Error
    func receive(subscription: Subscription)
    func receive(_ input: Input) -> Subscribers.Demand
    func receive(completion: Subscribers.Completion<Failure>)
}

カスタム Subscriber

ここでは Subscriber が最初に2つの値を要求し、受け取った値ごとにさらに1つ要求しながら、その都度出力します。

final class PrintSubscriber: Subscriber {
    typealias Input = Int
    typealias Failure = Never

    func receive(subscription: Subscription) {
        subscription.request(.max(2))
    }

    func receive(_ input: Int) -> Subscribers.Demand {
        print("Value:", input)
        return .max(1)
    }

    func receive(completion: Subscribers.Completion<Never>) {
        print("Done")
    }
}

Delegate API のラップ

カスタム Publisher の実用的な用途の1つは、デリゲートやコールバック API を Combine に橋渡しすることです。これにより、レガシーコードを組み合わせて扱えるようになります。Subscriber を保持し、デリゲートのコールバックを receive(_:) の呼び出しとして転送します。

可能なら Subject を優先

プロトコルを手作業で実装する必要は、ほとんどありません。多くの橋渡しでは、PassthroughSubject または CurrentValueSubject のほうがはるかに簡単です。send(_:) を呼び出すだけで済みます。

let subject = PassthroughSubject<Int, Never>()

subject
    .sink { print($0) }
    .store(in: &cancellables)

subject.send(1)
subject.send(2)

カスタム実装を使う場合

次のような場合は、カスタム Publisher/Subscriber 実装を検討してください:

  • バックプレッシャーをきめ細かく制御する必要がある
  • 複雑な Combine 以外のソースを効率的にラップする必要がある
  • 再利用可能で型安全なオペレーターが必要である

それ以外の場合は、Subject と組み込みオペレーターが適切な選択です。

確認問題

カスタム Publisher に関する知識を確認しましょう。

まとめ

Combine の中核プロトコルの実装方法を学びました:

  • Publisher は Subscriber ごとに Subscription を作成します
  • Subscription は Demand(バックプレッシャー)を尊重します
  • Subscriber は Subscription、値、完了を受け取ります
  • ほとんどの橋渡しでは Subject を優先します

これらの内部動作を理解すると、Combine 全体の仕組みがわかりやすくなります。

無料で開始

AI チューターと学ぶ Swift — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
122
レッスン
409

よくある質問

「カスタムPublisherとSubscriber」レッスンは無料ですか?

はい。「カスタムPublisherとSubscriber」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「カスタムPublisherとSubscriber」で何を学びますか?

独自のCombineコンポーネントを構築します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「カスタムPublisherとSubscriber」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ストリームの変換と結合
  2. スケジューラーとスレッド処理
  3. エラー処理演算子
  4. カスタムPublisherとSubscriber
← Swift Academyに戻る