这片主要介绍Combine基本用法
- let myPublisher = Just("1")
-
- let myScriber = Subscribers.Sink<String, Never> { completion in
- if completion == .finished {
- print("myScriber1 Finished")
- } else {
- print("myScriber1 Failure")
- }
- } receiveValue: { value in
- print(value)
- }
-
- myPublisher.subscribe(myScriber)
-
-
- 打印结果:
- // 1
- // myScriber1 Finished
1. Just发布一个Publisher,just只会发送一次,发送完成结束本次订阅
2. Sink订阅者,订阅了Just,这个Sink后面是个泛型
第一参数是参数类型,方法Just发送的是String类型,所以咱们观察者类型要保持一致
第二参数是错误类型,例子中参数是Never,就是不会报错,下面的例子中会介绍其它的
3. Sink中有两个闭包 (receiveCompletion和receiveValue)
receiveCompletion: 结束观察订阅
receiveValue: 订阅结果
- extension Publisher {
- public func sink(receiveCompletion: @escaping ((Subscribers.Completion<Self.Failure>) -> Void), receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
- }
-
- extension Publisher where Self.Failure == Never {
- public func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
- }
-
- // 如果不需要receiveCompletion,我们可以用Self.Failure == Never方法
Publishers处于pipline的最上游,它的主要作用是发送数据
- let arr = 0...3
- arr.publisher.sink { value in
- print(value)
- }
-
- 打印结果:
- // 0
- // 1
- // 2
- // 3
Combine给了我们一个简便的写法
适用环境,比如我们在意的是直接拿到结果,不需要中间的Operator
- class Person {
- var age: Int = 0 {
- didSet {
- print("age: \(age)")
- }
- }
- }
-
-
- let person = Person()
- let range = 0...2
- range.publisher.assign(to: \.age, on: person)
-
- 打印结果:
- // 0
- // 1
- // 2
keyPath
将发布者中的每个元素分配给对象上的属性。
使用Publisher/assign(to:on:)订阅者,当你想在每次发行者产生一个值时设置给定的属性。
在这个例子中,Publisher/assign(to:on:) 在person的实例上设置age属性的值
第二种用法
- class Person {
- @Published var age: Int = 0
- }
-
-
- let person = Person()
- Just(1).assign(to: &person.$age)
- print(person.age)
-
- 打印结果:
- // 1
熟悉SwiftUI的朋友看起来比较喜欢,属性包装器的写法
** assign 都是 Self.Failure == Never
- class Person {
- var age: Int = 0
- }
-
- let futurePubliser = Future<Int ,Never> { promise in
- print("异步操作")
- promise(.success(2))
-
- }
-
- let subscribers = Subscribers.Sink<Int,Never> { completion in
- if completion == .finished {
- print("Finished")
- } else {
- print("Failure")
- }
- } receiveValue: { value in
- print(value)
- }
-
- futurePubliser.subscribe(subscribers)
-
- let person = Person()
- futurePubliser.assign(to: \.age, on: person)
-
- 打印结果:
- // 异步操作
- // 2
- // Finished
Future和Just类似,区别在于:
Just直接发送参数, Failure = Never
Futrre是调用一个异步闭包,可以选择闭包结束时发送数据, Failure = Error
- let myPubliser2 = Just("1")
-
- let tansValue = Publishers.Map<Just<String>, Int>(upstream: myPubliser2) { value in
- return Int(value) ?? 0
- }
-
- let myScriber2 = Subscribers.Sink<Int,Never> { completion in
- if completion == .finished {
- print("Finished")
- } else {
- print("Failure")
- }
- } receiveValue: { value in
- print(value)
- }
-
- tansValue.subscribe(myScriber2)
-
- 打印结果:
- // 1
- // Finished
使用提供的闭包转换来自上游发布者的所有元素的发布者
Operator处于pipline的中游,它的主要作用是接收数据,处理数据,再发送数据
此发布者可能发布的错误类型, 此发布者使用其上游发布者的失败类型。
- _ = Just(1).filter({ value in
- return value < 10
- }).sink(receiveCompletion: { completion in
- if completion == .finished {
- print("Finished")
- } else {
- print("Failure")
- }
- }, receiveValue: { value in
- print(value)
- })
-
- 打印结果:
- // 1
- // Finished
- extension Just {
- public func filter(_ isIncluded: (Output) -> Bool) -> Optional<Output>.Publisher
- }
注意这个filter,它不是高阶函数里的那个filter,虽然它们功能都是数据过滤。但它属于Just, 它返回的是Publisher
- // 定义一个错误类型
- enum myErrors: Error {
- case wrongValue
- }
-
- // 定义一个publiser
- let publiser = CurrentValueSubject<String, myErrors>("10")
-
-
- // 第一个接收者
- publiser.filter {
- return $0.count < 2
- }.sink { completion in
- if completion == .failure(myErrors.wrongValue) {
- print("Scriber1 Finished")
- } else {
- print("Scriber1: \(completion)")
- }
- } receiveValue: { value in
- print("Scriber1: \(value)")
- }
-
- // 第二个接收者
- let myScriber = Subscribers.Sink<String,myErrors> { completion in
- if completion == .failure(myErrors.wrongValue) {
- print("Scriber2 Finished")
- } else {
- print("Scriber2: \(completion)")
- }
- } receiveValue: { value in
- print("Scriber2: \(value)")
- }
-
- publiser.subscribe(myScriber)
-
-
- // 开始发送数据
- publiser.send("1")
- publiser.send("11")
- publiser.send(completion: .failure(.wrongValue))
- publiser.send("over")
-
- 打印结果:
- // Scriber2: 10
- // Scriber1: 1
- // Scriber2: 1
- // Scriber2: 11
- // Scriber1 Finished
- // Scriber2 Finished
CurrentValueSubject可以订阅一个publiser, 它可以多点用send发布数据,直到发送completion结束观察
Failure = Error
- let subject1: CurrentValueSubject<Int,myErrors> = .init(10)
- let subject2: CurrentValueSubject<Int,myErrors> = .init(20)
-
- // 数据流 subject1 -> subject2
- _ = subject1.subscribe(subject2)
-
- let myScriber = Subscribers.Sink<Int,myErrors> { completion in
- if completion == .finished {
- print("Finished")
- } else {
- print("Failure")
- }
- } receiveValue: { value in
- print(value)
- }
-
- subject2.receive(subscriber: myScriber)
-
- subject1.send(1)
- subject1.send(2)
- subject2.send(3)
- subject1.send(completion: .failure(.wrongValue))
- subject1.send(11)
- subject2.send(12)
-
- 打印结果:
- // 10
- // 1
- // 2
- // 3
- // Failure
CurrentValueSubject也可以当作Operator适用
例子中subject1处于pipline的上游,subject2处于pipline的中游
Failure = Error
subject1.send(1) // subject1 -> subject2 ->Scriber
subject1.send(2) // subject1 -> subject2 ->Scriber
subject2.send(3) // subject2 ->Scriber
subject1.send(completion: .failure(.wrongValue)) // 结束myScriber的响应者
- let subject1: PassthroughSubject<Int,myErrors> = PassthroughSubject()
- let subject2: PassthroughSubject<Int,myErrors> = PassthroughSubject()
-
- // 数据流 subject1 -> subject2
- let cancelable = subject1.subscribe(subject2)
-
- let myScriber = Subscribers.Sink<Int,myErrors> { completion in
- if completion == .finished {
- print("Finished")
- } else {
- print("Failure")
- }
- } receiveValue: { value in
- print(value)
- }
-
- subject2.receive(subscriber: myScriber)
-
- subject1.send(1)
- subject1.send(2)
- subject2.send(3)
- subject1.send(completion: .failure(.wrongValue))
- subject1.send(11)
- subject2.send(12)
-
- 打印结果:
- // 1
- // 2
- // 3
- // Failure
PassthroughSubject和CurrentValueSubject功能类似
区别在于
CurrentValueSubject: 有个初始化值
PassthroughSubject:没有初始化值