Blockchain ク gainst to the list
This article uses the latest version of xcode 13 + macOS Big sur + iOS15
Subscribers to the Subscriber
Subscriber is also a protocol, which contains the Input data type, which corresponds to the Output type of Publisher and the amount of requested data.
Subscriber Agreement
Look at the Subscriber agreement first
public protocol Subscriber : CustomCombineIdentifierConvertible {
associatedtype Input
associatedtype Failure : Error
func receive(subscription: Subscription)
func receive(_ input: Self.Input) -> Subscribers.Demand
func receive(completion: Subscribers.Completion<Self.Failure>)
}
Copy the code
- CustomCombineIdentifierConvertible this is used to implement the agreement
Publisher
The unique ID of the stream, which the system has extended to implement. Input
Is the input type, corresponding toPublisher
theOutput
typeFailure
Is an error type, corresponding toPublisher
theFailure
typefunc receive(subscription: Subscription)
- Called when the Subscription is successful, passing the Subscription
- when
Subscriber
You’re ready to start receiving data, and you can callsubscription
therequest(_:)
Method requests data,request(_:)
passSubscribers.Demand
As a parameter.Subscribers.Demand.max
Maximum number of requestsSubscribers.Demand.none
Request 0 elementsSubscribers.Demand.unlimited
Infinite number of requests
func receive(_ input: Self.Input) -> Subscribers.Demand
- Called when the subscriber receives a message
input
Is to acceptInput
Type data- I need to return one
Subscribers.Demand
Indicates that several more parameters are to be received
func receive(completion: Subscribers.Completion<Self.Failure>)
- When the event ends the call
Next, define a Subscriber:
class TestSubscriber: Subscriber{
func receive(subscription: Subscription) {
print("Received Subscription")
subscription.request(.max(1))}func receive(_ input: Int) -> Subscribers.Demand {
print("Received Value", input)
return .unlimited
}
func receive(completion: Subscribers.Completion<Never>) {
print("Received completion")}}Copy the code
Simple run:
let sub = TestSubscriber()
(0 ..< 5).publisher.receive(subscriber: sub)
Copy the code
Running results:
Received Subscription
Received Value 0
Received Value 1
Received Value 2
Received Value 3
Received Value 4
Received completion
Copy the code
Func receive(subscription: subscription) ¶
subscription.request(.none)
Copy the code
Run again:
Received Subscription
Copy the code
No data and no completion.
Modify the code below:
.
func receive(subscription: Subscription) {
print("Received Subscription")
subscription.request(.max(2))}func receive(_ input: Int) -> Subscribers.Demand {
print("Received Value", input)
return .none
}
.
Copy the code
Run again:
Received Subscription
Received Value 0
Received Value 1
Copy the code
Modify the code again
.
func receive(_ input: Int) -> Subscribers.Demand {
print("Received Value", input)
return input = = 0 ? .max(2) : .none
}
.
Copy the code
Run again:
Received Subscription
Received Value 0
Received Value 1
Received Value 2
Received Value 3
Copy the code
By two modifications you can see that the number of accepted events is equal to the sum of the number of times subscription. Request plus the number returned by func receive(_ INPUT: Int) -> Subscribers.Demand.
sink
In Part I – Publisher many examples are used in the sink (receiveCompletion: receiveValue:), this method is by receiveCompletion and receiveValue closure to create subscriber to complete the subscription.
receiveCompletion
Called when Publisher returns is completereceiveValue
Called when an event is received.
Sink (receiveCompletion: receiveValue:) a subscription request immediately successful an infinite number of data, the returned Cancellable object must hold, or Cancellable is released, the data flow will be canceled.
You can use the sink(receiveValue:) method if there is no need to complete processing or errors.
assign
Assgin will assign the received data to properties marked as publishers for redistribution.
Assgin can assign the received data to properties via keypath or inout. Here’s an example:
class Test{
@Published var i: Int = 0
@Published var ii: Int = 0
}
Copy the code
The variables I and II need to be decorated with the @Published attribute. The @Published attribute marks the attributes as Published, and $is used to get the attribute for publisher. The @Published modified property is commonly used in SwiftUI development and is a good way to connect a View to a ViewModel.
Test the above code:
class Test{
@Published var i: Int = 0
@Published var ii: Int = 0
}
let test = Test(a)Just(1).assign(to: \.i, on: test)
Just(3).assign(to: &test.$ii)
test.$i.sink(receiveValue: { print("i".$0)})
test.$ii.sink(receiveValue: { print("ii".$0)})
Copy the code
The output is as follows:
i 1
ii 3
Copy the code