嗨,我有以下数据模型用于在我的应用中注册用户:
import Foundation
import Combine
import SwiftExtensions
class RegisterData {
@Published var firstName: String = ""
@Published var middleName: String = ""
@Published var lastName: String = ""
@Published var email: String = ""
@Published var postcode: String = ""
@Published var termsAggreed: Bool = false
@Published var receiveNews: Bool = false
}
extension RegisterData: Publisher {
typealias Output = Bool
typealias Failure = Never
func receive<S>(subscriber: S) where S : Subscriber, RegisterData.Failure == S.Failure, RegisterData.Output == S.Input {
// works only if debounce transform is removed or moved after all combineLatest transforms
let publisher = $firstName
.combineLatest($middleName, $lastName) { !$0.isEmpty && !$1.isEmpty && !$2.isEmpty }
.combineLatest($postcode, $email) { $0 && !$1.isEmpty && $2.isValidEmail }
.debounce(for: .seconds(0.5), scheduler: RunLoop.main) // try to debounce only texts, but not working
.combineLatest($receiveNews, $termsAggreed) { $0 && $1 && $2 }
.removeDuplicates()
.eraseToAnyPublisher()
publisher.receive(subscriber: subscriber)
}
}
我有一个视图控制器,其中有两个UITextField
和两个UISwitch
,它们填充了RegisterData
类的一个实例
我只想“反跳”存储字符串的属性的更改,因为用户将在文本字段中填充它们,但是我在func receive<S>(subscriber:)
中应用这些转换的方式是我需要的Publisher
使其不发送任何新值。如果我注释掉.debounce
转换,它将发送更新。如果我将.debounce
转换放在.removeDuplicates()
之前,它将发送更新,但是也会“反跳”布尔值。
String
进行去抖动?我尝试逐个反跳其中的每一个(让我们说其中一个拥有潜在的用户名,如果用户名是免费的,则必须在服务器上进行检查,因此我只想对它的API调用进行反跳),但并没有工作
谢谢!
答案 0 :(得分:0)
这个问题已经很老了,但是如果到目前为止您还没有找到解决方案,那么也许您正在寻找以下内容:
您的带有$前缀的字符串本身就是发布者,因此您可以通过在每个字符串上应用反跳操作符来简单地对其进行“反跳”。
您的代码如下所示:
let publisher = $firstName.debounce(for: .seconds(0.5), scheduler: RunLoop.main)
.combineLatest(
$middleName
.debounce(for: .seconds(0.5), scheduler: RunLoop.main),
$lastName
.debounce(for: .seconds(0.5), scheduler: RunLoop.main)) {
!$0.isEmpty && !$1.isEmpty && !$2.isEmpty
}
.combineLatest(
$postcode
.debounce(for: .seconds(0.5), scheduler: RunLoop.main),
$email
.debounce(for: .seconds(0.5), scheduler: RunLoop.main)) {
$0 && !$1.isEmpty && !$2.isEmpty
}
.combineLatest($receiveNews, $termsAggreed) { $0 && $1 && $2 }
.removeDuplicates()
.eraseToAnyPublisher()
代码重复很丑陋,但也许您可以对此进行扩展。