介绍
这个库和RxSwift一起使用,提供action的一个observable的抽象。
Action接受一个workFactory:接受一些输入,生成一个observable的闭包。当调用execute()时,它将其参数传递给此闭包,并subscrible此工作。
- 它只能在"enabled"状态被执行(如果未指定,则为true)
- 一次只执行一件事情
- 通过单次执行聚合next/error
而且它有一个非常cool的button,它将管理button的enabled状态,确保在您的工作完成后button被disabled.
使用
你必须传递一个workFactory:它接受输入,并返回一个observable。它代表着一些需要被完成的工作。当每次执行execute()是,它会传递输入给workFactory的输入。Action将订阅observable,并在其绑定元素的属性上发送next事件。如果observable出错,这个错误将作为next事件传递给error属性,
Action一次只能执行一件事情,如果你尝试执行一个现在正在执行的action,则会出现错误。executing属性将true或false值作为Next event传递。
action: Action<String, Bool> = Action(workFactory: { input in return networkLibrary.checkEmailExists(input) }) ... action.execute("ash@ashfurrow.com")
注意,第一个参数是泛型参数的类型,第二个是workFactory创建的observable的类型,你可以把它看做是action的输出。
你也可以给Action initilizer 指定enabledIf参数:
let validEmailAddress = emailTextField.rx.text.map(isValidEmail) action: Action<String, Bool> = Action(enabledIf: validEmailAddress, workFactory: { input in return networkLibrary.checkEmailExists(input) })
现在execute()只有在邮箱有效时才会执行. Super Cool!!
注意enabledIf和enabled property是不一样的,Action将根据传入的enabledIf和当前的执行状态来决定是否是enabled.
真正cool的是UIButton的扩展,它接受一个CocoaAction,它只是Action<void, void>
button.rx.action = action
现在,当按下按钮,操作被执行。这button的enabled状态被绑定到action的enabled属性,这意味着你可以将表单验证逻辑作为信号输入给action,当button为enabled时会自动处理。此外,用户不能在操作执行完毕之前再次点击按钮,因为它一个时间只能处理一个事情。Cool,来看一下CocoaAction的代码示例吧。
如果你想用Action做一个复杂的操作,例如带有进度条的下载文件(要更新UI中的进度条),你可以用Action<Void, Int> 代替
CocoaAction
. 开箱即用的CocoaAction不能发出进度值,而自己的Action<Void, Int>可以发出进度值,详细的信息可以餐卡这篇文章。
如果你的场景涉及许多按钮,它们有不同的输入但触发相同的Action,那么你可以在每个UIButton上使用bindTo绑定一个返回正确输入的闭包。
let button1 = UIButton() let button2 = UIButton() let action = Action<String, String> { input in print(input) return .just(input) } button1.rx.bindTo(action) { _ in return "Hello"} button2.rx.bindTo(action) { _ in return "Goodbye"}
button1和button2共用同一个Action,但是它们喂它不同的输入(hello和Goodbye会被打印对于相应的tap)
更复杂的用例是与UIViewController相关的单个Action,像管理你的导航、错误处理和加载状态。使用这种方法,你可以在一个公共位置一次性订阅 executing, errors, elements 和 completions。
还有一个cool的扩展是在UIAlertAction,被UIAlertController所使用。一个问题是:由于这个类的限制,您不能用普通的初始化器初始化它。相反,请调用如下类方法:
let action = UIAlertAction.Action("Hi", style: .default)
安装
只需要在你Podfile里添加一行:
pod 'Action'
然后运行pod install(它会自动把所依赖的RxSwift和RxCocoa安装好)