Interstellar

Build Status CocoaPods Version CocoaPods Plattforms Carthage compatible

你所能找到的最简单的函数式响应式编程 Observable<T> 实现。

这个库并没有按照 Conal Elliot 定义的方式使用 FRP (函数式响应式编程) 这个术语,而是将其作为一种既是函数式的又是响应式的范式。 阅读更多关于两者差异的信息:我为什么不能说FRP,但我刚刚说了

特性

要求


用法

有关此实现如何工作的完整指南,请参阅关于 Swift 中的函数式响应式编程 的系列博客文章,或在 UIKonf 2015 的演讲 如何在没有黑魔法的情况下使用函数式响应式编程

创建和更新信号

let text = Observable<String>()

text.subscribe { string in
  print("Hello \(string)")
}

text.update("World")

映射和转换 observables

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 也适用于 observables

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"

常见问题

为什么使用 Interstellar 而不是 [在此处插入您最喜欢的 FRP 框架]?

Interstellar 旨在轻量级。 没有 UIKit 绑定,没有繁重的结构 - 只有一个简单的 Observable<T>。 因此,它易于理解且可移植(除了 Foundation 之外没有任何依赖项)。

此外,Interstellar 还支持 BYOR(自带您的 Result<T>)。 由于其基于协议的实现,您可以直接将其他框架的结果类型与 Interstellar 方法一起使用。


贡献者

Interstellar 由 Jens Ravens 拥有和维护。

更新日志

许可证

Interstellar 是在 MIT 许可证下发布的。 有关详细信息,请参阅 LICENSE。