测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | Apache 2 |
发布上次发布 | 2017年4月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Jeff Verkoeyen 维护。
IndefiniteObservable
是一个没有完成或失败概念的、最小的 Observable 实现。
这个库由于大量使用泛型不支持 Objective-C。
导入框架
@import IndefiniteObservable;
您现在将能够访问所有 API。
运行以下命令以从仓库中获取本地副本,以便通过以下方式访问 Catalog 应用程序:
git clone https://github.com/material-motion/indefinite-observable-swift.git
cd observable-swift
pod install
open IndefiniteObservable.xcworkspace
在这个示例中,我们将创建最简单的可观察对象类型:一个值的可观察对象。我们将在所有以下指南中使用这个具体的类型。
final class ValueObserver<T>: Observer {
typealias Value = T
init(_ next: @escaping (T) -> Void) {
self.next = next
}
let next: (T) -> Void
}
final class ValueObservable<T>: IndefiniteObservable<ValueObserver<T>> {
func subscribe(_ next: @escaping (T) -> Void) -> Subscription {
return super.subscribe(observer: ValueObserver(next))
}
}
let observable = ValueObservable<<#ValueType#>> { observer in
observer.next(<#value#>)
return noopDisconnect
}
如果您有一个提供基于 blocks 的观察者注册机制的 API,则可以像这样创建异步流。
let observable = ValueObservable<<#ValueType#>> { observer in
let someToken = registerSomeCallback { callbackValue in
observer.next(callbackValue)
}
return {
unregisterCallback(someToken)
}
}
observable.subscribe { value in
print(value)
}
取消订阅将调用可观察对象的断开连接方法。要取消订阅,您必须保留由 `subscribe` 返回的订阅实例的引用。
let subscription = observable.subscribe { value in
print(value)
}
subscription.unsubscribe()
许多 iOS/macOS API 使用委托来实现事件处理。要将委托与流连接起来,您需要创建一个 Producer
类。一个 Producer
会监听事件,例如 didTap
,并将这些事件转发到一个 IndefiniteObservable 的观察器。
class DragConnection {
typealias Value = (state: UIGestureRecognizerState, location: CGPoint)
init(subscribedTo gesture: UIPanGestureRecognizer, observer: ValueObserver<Value>) {
self.gesture = gesture
self.observer = observer
gesture.addTarget(self, action: #selector(didPan))
// Populate the observer with the current gesture state.
observer.next(currentValue(for: gesture))
}
@objc func didPan(_ gesture: UIPanGestureRecognizer) {
observer.next(currentValue(for: gesture))
}
func currentValue(for gesture: UIPanGestureRecognizer) -> Value {
return (gesture.state, gesture.location(in: gesture.view!))
}
func disconnect() {
gesture?.removeTarget(self, action: #selector(didPan))
gesture = nil
}
var gesture: (UIPanGestureRecognizer)?
let observer: ValueObserver<Value>
}
let pan = UIPanGestureRecognizer()
view.addGestureRecognizer(pan)
let dragStream = ValueObservable<DragConnection.Value> { observer in
return DragConnection(subscribedTo: pan, observer: observer).disconnect
}
let subscription = dragStream.subscribe {
dump($0.state)
dump($0.location)
}
生产者应该是一种订阅类型。
class <#Name#>Producer: Subscription {
}
class DragConnection: Subscription {
typealias Value = (state: UIGestureRecognizerState, location: CGPoint)
}
您的初始化器必须接受并存储一个 ValueObserver<Value>
实例。
init(subscribedTo gesture: UIPanGestureRecognizer, observer: ValueObserver<Value>) {
self.gesture = gesture
self.observer = observer
}
var gesture: (UIPanGestureRecognizer)?
let observer: ValueObserver<Value>
init(subscribedTo gesture: UIPanGestureRecognizer, observer: ValueObserver<Value>) {
...
gesture.addTarget(self, action: #selector(didPan))
}
@objc func didPan(_ gesture: UIPanGestureRecognizer) {
observer.next(currentValue(for: gesture))
}
func currentValue(for gesture: UIPanGestureRecognizer) -> Value {
return (gesture.state, gesture.location(in: gesture.view!))
}
您负责在此处断开连接并释放任何资源。
func disconnect() {
gesture?.removeTarget(self, action: #selector(didPan))
gesture = nil
}
通常在注册时向观察器提供当前状态是有帮助的。
init(subscribedTo gesture: UIPanGestureRecognizer, observer: ValueObserver<Value>) {
...
// Populate the observer with the current gesture state.
observer.next(currentValue(for: gesture))
}
let dragStream = ValueObservable<DragConnection.Value> { observer in
return DragConnection(subscribedTo: pan, observer: observer).disconnect
}
let subscription = dragStream.subscribe {
dump($0)
}
此库旨在成为最小的实现,永远不增长。因此,我们只鼓励以文档、测试和示例的形式做出贡献。
了解有关 我们的团队、我们的社区 和我们 贡献者基础 的更多信息。
基于 Apache 2.0 许可协议。详情请参阅 LICENSE。