ios - Swift 将运算符与 RxSwift 框架中的 `withLatestFrom` 等功能相结合
问题描述
我正在开发一个采用 MVVM 模式的 iOS 应用程序,使用 SwiftUI 设计视图和 Swift 组合,以便将我的视图与它们各自的视图模型粘合在一起。在我的一个 ViewModel 中,我创建了一个Publisher
(type Void
) 用于按下按钮,另一个用于TextField
(type String
) 的内容。我希望能够在我的 ViewModel 中组合两个 Publisher,这样组合的 Publisher 仅在按钮 Publisher 在从 String 发布者获取最新事件时发出事件时才发出事件,因此我可以对TextField
数据进行某种评估,每次用户按下按钮。所以我的虚拟机看起来像这样:
import Combine
import Foundation
public class MyViewModel: ObservableObject {
@Published var textFieldContent: String? = nil
@Published var buttonPressed: ()
init() {
// Combine `$textFieldContent` and `$buttonPressed` for evaulation of textFieldContent upon every button press...
}
}
两个发布者都被 SwiftUI 填充了数据,所以我将省略这部分,让我们假设两个发布者随着时间的推移都会收到一些数据。
来自 RxSwift 框架,我的 goto 解决方案将是withLatestFrom运算符来组合两个可观察对象。但是,在“组合来自多个发布者的元素”部分中深入研究发布者的 Apple 文档时,我找不到类似的东西,所以我希望目前缺少这种运算符。
所以我的问题是:是否可以使用现有的组合框架的操作员 API 来获得相同的行为withLatestFrom
?
解决方案
对此有一个内置的运算符听起来很棒,但是您可以从已有的运算符中构造相同的行为,如果您经常这样做,则可以很容易地从现有的运算符中创建自定义运算符。
这种情况下的想法是combineLatest
与操作符一起使用,例如removeDuplicates
防止值在管道中传递,除非按钮发出了新值。例如(这只是操场上的一个测试):
var storage = Set<AnyCancellable>()
var button = PassthroughSubject<Void, Never>()
func pressTheButton() { button.send() }
var text = PassthroughSubject<String, Never>()
var textValue = ""
let letters = (97...122).map({String(UnicodeScalar($0))})
func typeSomeText() { textValue += letters.randomElement()!; text.send(textValue)}
button.map {_ in Date()}.combineLatest(text)
.removeDuplicates {
$0.0 == $1.0
}
.map {$0.1}
.sink { print($0)}.store(in:&storage)
typeSomeText()
typeSomeText()
typeSomeText()
pressTheButton()
typeSomeText()
typeSomeText()
pressTheButton()
输出是两个随机字符串,例如"zed"
和"zedaf"
。关键是每次我们调用时都会将文本发送到管道中typeSomeText
,但除非我们调用,否则我们不会在管道末端收到pressTheButton
文本。
这似乎是你所追求的那种东西。
你会注意到我完全忽略了按钮发送的值是什么。(在我的示例中,无论如何它只是一个 void。)如果该值很重要,则更改初始映射以将该值包含为元组的一部分,然后删除元组的 Date 部分:
button.map {value in (value:value, date:Date())}.combineLatest(text)
.removeDuplicates {
$0.0.date == $1.0.date
}
.map {($0.value, $1)}
.map {$0.1}
.sink { print($0)}.store(in:&storage)
这里的要点是,行后到达的内容与将产生的.map {($0.value, $1)}
内容完全相同:两个发布者的最新值的元组。withLatestFrom
推荐阅读
- unity3d - Unity2D随机战斗遭遇换场景?
- jquery - Visual Studio 中的 Jquery 没有智能感知
- python - 有没有办法创建一个包含 3 个或更多字段的 Python 内部表?
- reactjs - axios 会不断更新
- css - 如何查找具有多个包含条件的 xpath
- spring-boot - Spring Kafka 消费已被消费者消费的旧消息
- python - python内置服务器不加载css文件
- react-virtualized - React-virtualized 中对 registerChild 的 CellMeasurer 支持
- android - 如何在长按中从网页视图中获取 URL?
- .net - 覆盖默认的 nuget.config 文件