0Pricing
Swift Academy · Lekcja

Niestandardowi publisherzy i subskrybenci

Budowanie własnych komponentów Combine.

Niestandardowi publisherzy i subskrybenci to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Poza wbudowanymi publisherami

Combine zawiera wiele publisherów, ale czasami trzeba opakować API niezwiązane z Combine jako publisher albo odbierać wartości z precyzyjną kontrolą backpressure. Oznacza to samodzielną implementację protokołów Publisher i Subscriber.

Protokół Publisher

Publisher deklaruje typy Output i Failure oraz implementuje receive(subscriber:), przekazując subskrypcję do dołączającego subskrybenta.

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

Rola subskrypcji

Gdy subskrybent się dołącza, publisher tworzy obiekt Subscription. Subskrypcja jest połączeniem, które zarządza zapotrzebowaniem i dostarcza wartości. Jest zgodna z Subscription, które rozszerza Cancellable.

Niestandardowa subskrypcja

Subskrypcja przechowuje subskrybenta i odpowiada na żądania zapotrzebowania, emitując wartości.

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
    }
}

Niestandardowy publisher

Publisher po prostu tworzy subskrypcję i przekazuje ją subskrybentowi za pośrednictwem receive(subscription:).

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)
    }
}

Zrozumienie zapotrzebowania

Backpressure to mechanizm kontroli przepływu w Combine. Subskrybent żąda określonego poziomu Demand, a publisher nie może wysłać więcej wartości, niż zażądano. Zwrócenie zapotrzebowania z receive(_:) zwiększa dozwolony limit.

Protokół Subscriber

Niestandardowy Subscriber implementuje trzy metody: odbiera subskrypcję, następnie każdą wartość, a na końcu informację o zakończeniu.

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

Niestandardowy subskrybent

W tym przykładzie subskrybent od razu żąda dwóch wartości, a następnie jednej dodatkowej za każdą odebraną wartość, wypisując je w miarę odbierania.

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")
    }
}

Opakowywanie API opartego na delegacie

Praktycznym zastosowaniem niestandardowych publisherów jest połączenie API opartego na delegacie lub wywołaniach zwrotnych z Combine, dzięki czemu starszy kod staje się kompozycyjny. Należy przechować subskrybenta i przekazywać wywołania delegata jako wywołania receive(_:).

Jeśli to możliwe, używaj subjectów

Ręczne implementowanie protokołów rzadko jest konieczne. W większości przypadków integracji znacznie prostsze jest użycie PassthroughSubject lub CurrentValueSubject — wystarczy wywołać send(_:).

let subject = PassthroughSubject<Int, Never>()

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

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

Kiedy wybrać własną implementację

Warto sięgnąć po niestandardowe implementacje Publisher/Subscriber, gdy potrzebne są:

  • precyzyjna kontrola backpressure
  • wydajne opakowanie złożonego źródła niezwiązanego z Combine
  • wielokrotnego użytku, bezpieczne typowo operatory

W przeciwnym razie właściwym wyborem są subjecty i wbudowane operatory.

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat niestandardowych publisherów.

Podsumowanie

Poznali Państwo implementację podstawowych protokołów Combine:

  • Publisher tworzy obiekt Subscription dla każdego subskrybenta
  • Subskrypcja respektuje Demand (backpressure)
  • Subscriber odbiera subskrypcję, wartości i informację o zakończeniu
  • W większości przypadków integracji należy preferować subjecty

Zrozumienie tych szczegółów wyjaśnia działanie całego Combine.

Często zadawane pytania

Czy lekcja „Niestandardowi publisherzy i subskrybenci” jest bezpłatna?

Tak — pełny tekst „Niestandardowi publisherzy i subskrybenci” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Niestandardowi publisherzy i subskrybenci”?

Budowanie własnych komponentów Combine. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Niestandardowi publisherzy i subskrybenci”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Przekształcanie i łączenie strumieni
  2. Harmonogramy i wątki
  3. Operatory obsługi błędów
  4. Niestandardowi publisherzy i subskrybenci
← Powrót do Swift Academy