I tried to follow the code snippet of WWDC 2019's Combine in Practice talk (starting at minute 26:00) or see slides 179 ff. but it won't compile and looking at the API some parts don't make sense to me (e.g., calling CombineLatest.init(A, B)
with a third argument of type closure
. I tried to adapt the examples so they compile.
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: CombineLatest<Published<String>, Published<String>, String?> {
return CombineLatest($password, $passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
}
I can only get this snippet to at least return me the Publisher from
CombineLatest`
Publishers
enum to the namespace of CombineLatest
.Publisher
to Published<String>
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher> {
return Publishers.CombineLatest($password, $passwordAgain)
}
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Map<CombineLatest<Published<String>, Published<String>, String?>> {
return CombineLatest($password, $passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map { $0 == "password1" ? nil : $0 }
}
I can get this snippet to compile when:
Publishers.
in front of Map
<>
to the correct positionPublishers.Map
explicitly and by using the correct parameter upstream:
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?> {
return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
or when including the .map {}
from the slide:
Publishers.Map<..., String?>
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.Map<Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?>, String?> {
return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map { $0 == "password1" ? nil : $0 }
}
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: AnyPublisher<String?, Never> {
return Just($password)
.combineLatest($passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map{ $0 == "password1" ? nil : $0 }
.eraseToAnyPublisher()
}
On Q1:
WWDC demos were using API existed at that time. Time passed - API changed. That's it.
On Q2:
Try instead like the following...
var validatedPassword: AnyPublisher<String?, Never> {
return Publishers.CombineLatest($password, $passwordAgain)
.map { password, passwordRepeat in
guard password == passwordRepeat, password.count > 8 else { return nil }
return password
}
.map { ($0 ?? "") == "password1" ? nil : $0 }
.eraseToAnyPublisher()
}