您能找到的最简单的 Observable<T>
实现,用于函数式响应式编程。
这个库没有使用 Conal Elliot 定义的 FRP(函数式响应式编程)术语,而是一种既函数式又响应式的方法论。有关差异的更多信息,请参阅为什么我说不出 FRP 但我确实做到了。
特性
- 轻量级、简单、跨平台的 FRP
- 使用 GCD 实现多线程变得简单
- 您的大部分方法将符合所需的语法。
- Swift 3 和 4 兼容性
- 通过 WarpDrive,多线程的 GCD 变得简单
- 支持 Linux 和
swift build
- BYOR™ 技术(自带
Result<T>
)
要求
- iOS 7.0+ / Mac OS X 10.10+ / Ubuntu 14.10
- Xcode 8
使用方法
有关此实现如何工作的全面指南,请参阅有关Swift 中函数式响应式编程的一系列博客文章或 UIKonf 2015 的演讲如何使用没有黑魔法的函数式响应式编程。
创建和更新信号
let text = Observable<String>()
text.subscribe { string in
print("Hello \(string)")
}
text.update("World")
映射和转换可观察对象
let text = Observable<String>()
let greeting = text.map { subject in
return "Hello \(subject)"
}
greeting.subscribe { text in
print(text)
}
text.update("World")
将函数用作转换
let text = Observable<String>()
let greet: (String)->String = { subject in
return "Hello \(subject)"
}
text
.map(greet)
.subscribe { text in
print(text)
}
text.update("World")
处理函数序列中的错误
let text = Observable<String>()
func greetMaybe(subject: String) throws -> String {
if subject.characters.count % 2 == 0 {
return "Hello \(subject)"
} else {
throw NSError(domain: "Don't feel like greeting you.", code: 401, userInfo: nil)
}
}
text
.map(greetMaybe)
.then { text in
print(text)
}
.error { error in
print("There was a greeting error")
}
text.update("World")
这也适用于异步函数
let text = Observable<String>()
func greetMaybe(subject: String) -> Observable<Result<String>> {
if subject.characters.count % 2 == 0 {
return Observable(.success("Hello \(subject)"))
} else {
let error = NSError(domain: "Don't feel like greeting you.", code: 401, userInfo: nil)
return Observable(.error(error))
}
}
text
.flatMap(greetMaybe)
.then { text in
print(text)
}
.error { _ in
print("There was a greeting error")
}
text.update(.success("World"))
Flatmap 也可在可观察对象上进行使用
let baseCost = Observable<Int>()
let total = baseCost
.flatMap { base in
// Marks up the price
return Observable(base * 2)
}
.map { amount in
// Adds sales tax
return Double(amount) * 1.09
}
total.subscribe { total in
print("Your total is: \(total)")
}
baseCost.update(10) // prints "Your total is: 21.8"
baseCost.update(122) // prints "Your total is: 265.96"
通信
- 如果您找到 错误,请提交一个问题。
- 如果您有 功能请求,请提交一个问题。
- 如果您想要 贡献,请提交一个问题或提出拉取请求。
安装
在iOS上,动态框架需要最低部署目标为iOS 8及以上。为了使用针对iOS 7的项目与Interstellar结合,必须将所有Swift文件直接包含在项目中。
CocoaPods
CocoaPods 是一个Cocoa项目的依赖管理器。你可以使用以下命令安装它
$ gem install cocoapods
使用CocoaPods将Interstellar集成到Xcode项目中时,在您的 Podfile
中指定它
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'Interstellar'
然后,运行以下命令
$ pod install
swift build
将Interstellar添加到你的 Package.swift
import PackageDescription
let package = Package(
name: "Your Awesome App",
targets: [],
dependencies: [
.Package(url: "https://github.com/jensravens/interstellar.git", majorVersion: 2),
]
)
Carthage
Carthage 是一个用于自动将框架添加到您的Cocoa应用程序中的去中心化依赖管理器。
您可以使用以下命令使用 Homebrew 安装Carthage
$ brew update
$ brew install carthage
使用Carthage将Interstellar集成到您的Xcode项目中时,在您的 Cartfile
中指定它
github "JensRavens/Interstellar"
常见问题解答(FAQ)
为何使用Interstellar而不是[插入你喜欢的FRP框架名称]?
Interstellar旨在轻量级。没有UIKit绑定,没有沉重的构建,仅包含简单的Observable
。因此,它易于理解和可移植(不依赖除Foundation外的任何东西)。
此外,Interstellar支持BYOR(带上你自己的Result
)。由于其基于协议的实现,您可以直接使用其他框架中的结果类型与Interstellar方法结合使用。
致谢
Interstellar由Jens Ravens所有并维护。
更新日志
- 1.1 增加与Swift 2的兼容性。将bind重命名为flatMap以与
Optional
和Array
保持一致。 - 1.2 将
Thread
移动到新的项目WarpDrive中。 - 1.3 将WarpDrive合并到Interstellar中。现在,Interstellar通过cocoapods分割为子模块,以便轻松选择所需组件。基本的信号库现在是"Interstellar/Core"。
- 1.4 支持使用
swift build
和新的Swift包管理器,包括对Linux的支持。另外,移除了过时的bind方法。 - 2 介绍
Observable
,Signal的继任者。使用信号上的observable
属性将代码从Signal
迁移过来。还引入了Warpdrive对Linux的支持和BYOR™技术(带上你自己的Result
)。 - 2.1 升级到Swift 3.2以与Swift 4兼容。
- 2.2 升级到Swift 4.1,修复了Xcode 9.3上的编译警告(与Swift 3.3项目保持向后兼容)。
许可证
Interstellar在MIT许可证下发布。有关详细信息,请参阅LICENSE。