信号 6.1.0

信号 6.1.0

测试已测试
Lang语言 SwiftSwift
证书 MIT
发布最新发布2019年4月
SPM支持SPM

Tuomas Artman维护。



信号 6.1.0

信号

Build Status Cocoapods Compatible Carthage Compatible License Platform Twitter

信号是一个创建和观察事件的库。它用更强大、更优雅的东西取代了代理、操作和NSNotificationCenter。

特点

  • 附加并忘记观察
  • 类型安全
  • 过滤观察
  • 延迟和队列观察
  • 全面的单元测试覆盖

要求

  • iOS 7.0 / watchOS 2.0 / Mac OS X 10.9
  • Swift 4.2

安装

要将信号与针对iOS 7的目标项目一起使用,只需将Signals.swift复制到您的项目中。

CocoaPods

要将 Signals 集成到您的项目中,请将以下内容添加到您的 Podfile

platform :ios, '8.0'
use_frameworks!

pod 'Signals', '~> 6.0'

Carthage

使用 Carthage 将 Signals 集成到您的项目中,请将以下内容添加到您的 Cartfile

github "artman/Signals" ~> 6.0

Swift Package Manager

使用 SwiftPM 将 Signals 集成到您的项目中,请将以下内容添加到您的 Package.swift

dependencies: [
    .package(url: "https://github.com/artman/Signals", from: "6.0.0"),
],

快速入门

通过创建一个或多个信号,使类的事件可观察

class NetworkLoader {

    // Creates a number of signals that can be subscribed to
    let onData = Signal<(data:NSData, error:NSError)>()
    let onProgress = Signal<Float>()

    ...

    func receivedData(receivedData:NSData, receivedError:NSError) {
        // Whenever appropriate, fire off any of the signals
        self.onProgress.fire(1.0)
        self.onData.fire((data:receivedData, error:receivedError))
    }
}

从应用程序的其它地方订阅这些信号

let networkLoader = NetworkLoader("http://artman.fi")

networkLoader.onProgress.subscribe(with: self) { (progress) in
    print("Loading progress: \(progress*100)%")
}

networkLoader.onData.subscribe(with: self) { (data, error) in
    // Do something with the data
}

向 Signals 添加订阅是一个附件和忘记的操作。如果订阅的对象被释放,Signal 会取消订阅,所以您不需要显式管理您订阅的取消。

信号不受限于一个订阅者。多个对象可以订阅同一个信号。

您还可以在事件发生后订阅这些事件

networkLoader.onProgress.subscribePast(with: self) { (progress) in
    // This will immediately fire with last progress that was reported
    // by the onProgress signal
    println("Loading progress: \(progress*100)%")
}

高级主题

信号订阅可以应用过滤器

networkLoader.onProgress.subscribe(with: self) { (progress) in
    // This fires when progress is done
}.filter { $0 == 1.0 }

您可以通过抽样来降低订阅执行频率,而不管 Signal 多么频繁地触发

networkLoader.onProgress.subscribe(with: self) { (progress) in
    // Executed once per second while progress changes
}.sample(every: 1.0)

默认情况下,订阅会在触发 Signal 的线程上同步执行。要更改默认行为,您可以使用 dispatchOnQueue 方法来定义分发队列

networkLoader.onProgress.subscribe(with: self) { (progress) in
    // This fires on the main queue
}.dispatchOnQueue(DispatchQueue.main)

如果您不喜欢在触发包含元组的信号时使用的双引号,可以使用自定义的 => 操作符来触发数据

// If you don't like the double quotes when firing signals that have tuples
self.onData.fire((data:receivedData, error:receivedError))

// You can use the => operator to fire the signal
self.onData => (data:receivedData, error:receivedError)

// Also works for signals without tuples
self.onProgress => 1.0

替换动作

信号扩展了所有从UIControl派生的类(不在OS X上可用),并允许您使用信号来监听控件事件,提高代码的局部性。

let button = UIButton()
button.onTouchUpInside.observe(with: self) {
    // Handle the touch
}

let slider = UISlider()
slider.onValueChanged.observe(with: self) {
    // Handle value change
}

替换代理

信号简单且现代,大大减少了设置委托所需的样板代码。

您更愿意使用代理实现回调吗?

  • 创建一个用于定义委托的协议
  • 在希望提供委托的类上创建一个委托属性
  • 标记所有想要成为代理的类以遵守代理协议
  • 在想要成为代理的类上实现委托方法
  • 设置委托属性以将实例成为代理
  • 在调用它之前检查您的代理是否实现了每个委托方法

或者用信号做同样的事情

  • 为想要提供事件的类创建一个信号
  • 订阅信号

替换NotificationCenter

随着工程师团队的壮大,NotificationCenter很快就会变成一个反模式。具有隐式数据且无编译器保护的全球通知很容易使您的代码出错,难以维护和重构。

用信号替换NotificationCenter将为您提供由编译器强制执行的类型安全性,这有助于您在快速移动时维护代码。

通信

  • 如果您发现了一个错误,请打开一个问题或通过拉取请求提交修复。
  • 如果您有功能请求,请打开一个问题或通过拉取请求提交实现,或者通过Twitter联系我 @artman
  • 如果您希望贡献,请在主分支上提交一个拉取请求。

许可协议

Signals 在MIT许可下发布。有关更多信息,请参阅LICENSE文件。