Combine: 3 примера использования Publishers и Subscriber | OTUS

Combine: 3 примера использования Publishers и Subscriber

ios_deep_22.8-5020-95af92.png

На конференции WWDC 2019 был представлен новый фреймворк Combine. Всё последнее десятилетие среди программистов становились популярными декларативный и Event-based подходы к разработке приложений, т. к. они дают преимущество в скорости разработки приложений.

Combine предоставляет следующие возможности: 1. Асинхронное выполнение кода. 2. Составные компоненты. 3. Более простой мультитрединг. 4. Кроссплатформенный код.

Combine позволяет выполнять код «реактивно».

Publishers and Subscribers

Основой Combine является 2 концепции: 1. Subscriber выполняет роль Observer. 2. Publisher выполняет роль Observable.

Самый короткий пример их использования:

import Combine

let pub = Just("Hello")

_ = pub.sink {
    print($0)
}

Объявляем константу, где в структуру Just оборачивается строка "Hello", — это наш паблишер, который оповестит только раз. Ниже добавляем подписку с замыканием с помощью метода sink. И этот пример напечатает в итоге строку Hello.

@Published Property Wrapper

В Swift 5.1 появилась возможность использовать Property Wrappers, которые изначально назывались Property Delegates. Это очередная обёртка в виде структуры, позволяющая добавлять на чтение или запись свойства (property) дополнительное поведение. Combine же даёт возможность использовать их через @Published.

import Foundation
import Combine

class ObjectWithPublisher {
    @Published var someString: String = ""
}

var obj = ObjectWithPublisher()
obj.$someString.sink(receiveValue: { print ("\($0)") })

obj.someString = "Hello Combine!"

Обращаться к таким врапперам можно, используя $ перед свойством. Как и в прошлом примере, мы добавляем Subcriber с помощью метода sink, но свойство мы обновляем позже подписки. В итоге этот пример распечатает нам “Hello Combine!”

Subjects

В Combine такие сущности, как Subject также являются паблишерами, которым мы можем посылать события. Сейчас у нас есть 2 вида Subjects: 1. PassthroughSubject, с помощью которого вы получите все события, которые случились после вашей подписки. 2. CurrentValueSubject — получите всё тоже, что и с помощью PassthroughSubject, но также и предыдущее или инициализированное значение

import Combine

let subj = PassthroughSubject<String, Never>()
let pub = subj.eraseToAnyPublisher()

subj.send("Hello")

let subscriber = pub.sink(receiveValue: { print($0) })

subj.send("Combine")
subj.send("!")

Объявление Subjects требует от нас, чтобы кроме выходного типа мы также указали тип для ошибки, можем просто указать здесь Never. Функция eraseToAnyPublisher() делает нам Type Erasure для паблишера к типу AnyPublisher. Дальше уже знакомая нам подписка с помощью sink. События мы будет посылать с помощью метода send и получим лишь 2 последних отправления:

Combine
!
import Combine

let subj = CurrentValueSubject<String, Never>("Bonjour")
let pub = subj.eraseToAnyPublisher()

subj.send("Hello")

let subscriber = pub.sink(receiveValue: { print($0) })

subj.send("Combine")
subj.send("!")

Использование CurrentValueSubject отличается тем, что нам нужно указать начальное значение. И результат мы получим :

Hello
Combine
!

Если же мы не закомментируем первое отправление до подписки, то вместо Hello нам придёт начальная строка Bonjour.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто