## [Subscriber](https://developer.apple.com/documentation/combine/subscriber)

![Combine](/pictures/Swift/Combine.jpg?raw=true)

**Subscriber** — это конечная точка потока данных, далее будем называть его подписчик. По сути это объект, который подписывается на паблишер и взаимодействуют с полученными и паблишера данными. В Combine, имеется 2 встроенных подписчика: **Sink** и **Assign**, оба соответствуют протоколу Subscriber.

Протокол представлен с двумя ассоциированными типами: `Input` и `Failure`.

`Input` — данные определенного типа, который он может обработать.

`Failure` — ошибка, которая может прийти от паблишера.

```swift
public protocol Subscriber<Input, Failure> : CustomCombineIdentifierConvertible {
    associatedtype Input
    associatedtype Failure: Error
}
```

### Sink

`.sink` — это и есть подписчик, метод создает подписчика и сразу запрашивает неограниченное число значений. Посмотрите на его сигнатуру:

```
func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
```

Пример:

```swift
sequencePublisher
    .sink { receivedValue in
        print(receivedValue)
    }
```

Метод .sink() возвращает объект с типом AnyCancellable — это класс-обертка, которая стирает тип данных подписчика.

У AnyCancellable есть 2 метода:

`.cancel()` — позволяет отменять подписку на паблишер. Мы можем его вызвать ручками при необходимости, но AnyCancellable может вызывать его автоматически при деинициализации объекта, если мы сохраним подписку с помощью второго метода.

`.store(in:)` — позволяет сохранить подписку на паблишер в коллекцию. 

### Assign

https://shayanbo.medium.com/dive-in-combine-part-iii-6eeb0aab2304

В большинстве случаев Sink достаточно. Но когда мы работаем над обновлением свойств экземпляра путем подписки на Publisher. Для нас есть более простой подписчик под названием Assign. Мы можем использовать Assign для обновления свойств, указав его KeyPath.

Пример:
```swift
class Person {
    @Published var name = "Yanbo Sha"
}
class View {
    var text = ""
}
let view = View()
let person = Person()
let cancellable = person.$name.assign(to: \.text, on: view)
person.name = "Rock"
print(view.text) /// "Rock" 
```

---

[4.1.4.4 Operators Theme](./4.1.4.4%20Operators.md) | [Back To iTWiki Contents](https://github.com/eldaroid/iTWiki) | [4.2 DevTools Theme Folder](/4%20Linkage/4.2%20DevTools/)