Comebine Features
Generic
Type safe
Composition first
Request driven
Publisher
Defines how values and errors are produced
Value type
Allows registration of a Subscriber
protocol Publisher {
associatedtype Output
associatedtype Failure: Error
func subscribe<S: Subsriber>(_ subscriber: S)
where S.Input == Output, S.Failure == Failure
}
example in Notification
extension NotificationCenter {
struct PublisherL Combine.Publisher {
typealias Output = Notification
type alias Failure = Never
init(center: NotificationCenter, name: Notification.Name, object: Any? = nil)
}
}
Subscriber
Receives values and a completion
Reference type
protocol Subscriber {
associatedtype Input
associatedtype Failure: Error
func receive(subscription: Subscription)
func receive(_ input: Input) -> Subscribers.Demand
func receive(completion: Subscribers.Completion<Failure>)
}
Assign
extension Subscribers {
class Assign<Root, Input>: Subscriber, Cancellable {
type alias Failure = Never
init(object: Root, keyPath: ReferenceWritableKeyPath<Root, Input>)
}
}
The Pattern
Subscriber is attached to Publisher
Publisher sends a Subscription
Subscriber requests N values
Publisher sends N values or less
Publisher sends completion
Operator
Adopts Publisher
Describes a behavior for changing values
Subscribes to a Publisher ("upstream")
Sends result to a Subscriber ("downstream")
Value type
Map
extension Publishers {
struct Map<Upstream: Publisher, Output>: Publisher {
type alias Failure = Upstream.Failure
let upstream: Upstream
let transform: (Upstream.Output) -> Output
}
}
//Using Operators
let graduationPublisher = NotificationCenter.Publisher(center: .default, name: .graduated, object: merlin)
let gradeSubscriber = Subscribers.Assign(object: merlin, keyPath: \.grade)
let converter = Publishers.Map(upstream: graduationPublisher) { note in
return note.userInfo?["NewGrade"] as? Int ?? 0
}
converter.subscribe(gradeSubscriber)
//the heart of how to use combine
//Chained Publishers
let cancellable =
NotificationCenter.default.publisher(for: .graduated, object: merlin)
.map { note in
return note.userInfo?["NewGrade"] as? Int ?? 0
}
.assign(to: \.grade, on: merlin)
Declarative Operator API
Functional transformations
List operations
Error handling
Thread or queue movement
Scheduling and time
Combining Publishers
Zip
CombineLatest
Zip
Converts several inputs into a single tuple
A "when/and" operation
Requires input from all to proceed
Stores last value
等待三个事件完成改变按钮状态
Zip3(organizing, decomposing, arranging)
.map { $0 && $1 && $2 }
.assign(to: \.isEnabled, on: continueButton)
Try it
Process a NotificationCenter post with filter
Await completion of two network requests with zip
decode the data of a URLResponse
More to Combine
Error handling and cancellation
Schedulers and time
Design patterns
//more in
Combine in Practice //WWDC 2019











网友评论