Platforms Carthage Compatible Swift Package Manager Compatible Xcode version

现代应用程序通常包含复杂的异步流程和生命周期。 Flow 是一个 Swift 库,旨在通过解决以下三个主要问题来简化这些流程的构建:

Flow 的设计非常周到,力求做到:

使用示例

在 Flow 中,Disposable 协议用于生命周期管理

extension UIView {
  func showSpinnerOverlay() -> Disposable {
    let spinner = ...
    addSubview(spinner)
    return Disposer {
      spinner.removeFromSuperview()
    }
  }
}

let disposable = view.showSpinnerOverlay()

disposable.dispose() // Remove spinner

Disposable 资源可以收集在一个公共的 DisposeBag

let bag = DisposeBag() // Collects resources to be disposed together

bag += showSpinnerOverlay()
bag += showLoadingText()

bag.dispose() // Will dispose all held resources

Signal<T> 类型用于事件处理。信号由标准 UI 组件提供

let bag = DisposeBag()

// UIButton provides a Signal<()>
let loginButton = UIButton(...)

bag += loginButton.onValue {
  // Log in user when tapped
}

// UITextField provides a ReadSignal<String>
let emailField = UITextField(...)
let passwordField = UITextField(...)

// Combine and transform signals
let enableLogin: ReadSignal<Bool> = combineLatest(emailField, passwordField)
  .map { email, password in
    email.isValidEmail && password.isValidPassword
  }

// Use bindings and key-paths to update your UI on changes
bag += enableLogin.bindTo(loginButton, \.isEnabled)

最后,Future<T> 类型处理异步操作

func login(email: String, password: String) -> Future<User> {
  let request = URLRequest(...)
  return URLSession.shared.data(for: request).map { data in
    User(data: data)
  }
}

login(...).onValue { user in
  // Handle successful login
}.onError { error in
  // Handle failed login
}

这三种类型带有许多扩展,允许我们组合复杂的 UI 流程

class LoginController: UIViewController {
  let emailField: UITextField
  let passwordField: UITextField
  let loginButton: UIButton
  let cancelButton: UIBarButtonItem

  var enableLogin: ReadSignal<Bool> { /* Introduced above */ }
  func login(email: String, password: String) -> Future<User> { /* Introduced above */ }
  func showSpinnerOverlay() -> Disposable { /* Introduced above */ }

  // Returns future that completes with true if user chose to retry
  func showRetryAlert(for error: Error) -> Future<Bool> { ... }

  // Will setup UI observers and return a future completing after a successful login
  func runLogin() -> Future<User> {
    return Future { completion in // Complete the future by calling this with your value
      let bag = DisposeBag() // Collect resources to keep alive while executing

      // Make sure to signal at once to set up initial enabled state
      bag += enableLogin.atOnce().bindTo(loginButton, \.isEnabled)  

      // If button is tapped, initiate potentially long running login request using input
      bag += combineLatest(emailField, passwordField)
        .drivenBy(loginButton)
        .onValue { email, password in
          login(email: email, password: password)
            .performWhile {
              // Show spinner during login request
              showSpinnerOverlay()
            }.onErrorRepeat { error in
              // If login fails with an error show an alert...
              // ...and retry the login request if the user chooses to
              showRetryAlert(for: error)
            }.onValue { user in
              // If login is successful, complete runLogin() with the user
              completion(.success(user))
        }
      }

      // If cancel is tapped, complete runLogin() with an error
      bag += cancelButton.onValue {
        completion(.failure(LoginError.dismissed))
      }

      return bag // Return a disposable to dispose once the future completes
    }
  }
}

要求

安装

Carthage

github "iZettle/Flow" >= 1.0

Cocoa Pods

platform :ios, '9.0'
use_frameworks!

target 'Your App Target' do
  pod 'FlowFramework', '~> 1.0'
end

Swift Package Manager

import PackageDescription

let package = Package(
  name: "Your Package Name",
  dependencies: [
      .Package(url: "https://github.com/iZettle/Flow.git",
               majorVersion: 1)
  ]
)

介绍

可以在以下位置找到 Flow 主要领域的介绍:

为了了解更多关于可用功能的信息,我们鼓励您浏览经过广泛文档记录的源文件。代码完成也应该帮助您发现信号和 future 上可用的许多转换。

了解更多

要了解更多关于 Flow API 背后的设计,我们建议阅读以下文章。 它们更深入地探讨了 Flow 的类型和 API 的外观和行为方式,并让您深入了解它们的实现方式

要了解如何使用 Flow 构建其他框架

基于 Flow 构建的框架

如果您的目标是 iOS,我们强烈建议您还查看这些基于 Flow 构建的框架

实地测试

Flow 经过数年的开发、演变和实地测试,并在 iZettle 广受好评的销售点应用程序中得到广泛应用。

协作

您可以在我们的 Slack 工作区与我们协作。 提出问题,分享想法,或者只是参与正在进行的讨论。 要获取邀请,请写信至 iz-apps-platform-ios@paypal.com