CombineLatest3(read, practiced, approved) { $0 && $1 && $2
}
.assign(to: .isEnabled, on: playButton)
import Combine
Publishers.CombineLatest3(read, practiced, approved).map {
$0 && $1 && $2
}
read.combineLatest(practiced, approved) {
$0 && $1 && $2
}
15 swift 0x00000001089a9f53 main + 1283
16 libdyld.dylib 0x00007fff69cc4cc9 start + 1
17 libdyld.dylib 0x000000000000004b start + 2519970691
error: Segmentation fault: 11 (in target 'ZipCombineOperators' from project 'ZipCombineOperators')
import UIKit
import Combine
class ViewController: UIViewController {
@Published var password:String = ""
@Published var passwordAgain:String = ""
@Published var validatedPassword:Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// validatedPassword.CombineLatest($confirmPassword,$password){
// return $0 && $1
// }
}
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
}
}
}
When does it crash? Compile or run?
Compile time (may be XCode Bug)
First, I'd urge you to file a bug report with these lines (it should never crash the compiler, and the compiler should correctly tells you what's wrong).
class ViewController: UIViewController {
@Published var validatedPassword= false
var validatedPassword: Bool { false }
}
It's not a valid code (you have validatedPassword
twice), but it should never crash the compiler. The compiler should correctly tells you what's wrong.
As mentioned above, you just created two variables with the same name, which is not allowed.
Even then, the computed property validatedPassword
you make won't work, or even compile, so I'll just explain it here.
-
CombineLatest
is part ofPublishers
. You can not just refer to it asCombineLatest
, you need to sayPublishers.CombineLatest
. - You need to check what type signature you function actually have. Even if the function is named
combineLatest
, it doesn't actually returnCombineLatest
(or should I say,Publishers.CombineLatest
). The documentation about it is right here. You should instead write:
return $password.combineLatest($passwordAgain) { (password, passwordAgain) -> String? in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
Now, what should actual return type be. The doc says that this function returns a Publishers.Map<Publishers.CombineLatest<Self, P>, T>
object. This has two generic parameter, P
and T
, so we need to figure them out. It also mentions Self
so that too.
-
$password
is aprojectedValue
ofPublished
. If you're confused about thePublished
, you can try asking again in a new thread. Since thewrappedValue
isString
, theprojectedValue
, henceSelf
, isPublished<Value>.Publisher
. - The first argument is of type
P
, so the it should match the type of$passwordAgain
which isPublished<String>.Publisher
. - The
transform
closure takes bothOutput
of the publishers, and produceT
, soT
should beString?
since our closure returnsString?
.
Substituting all the types in, you can figured out that the return type of that expression is:
Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?>
So your actual property should look like this:
var validatedPassword: Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?> {
return $password.combineLatest($passwordAgain) { (password, passwordAgain) -> String? in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
}
And don't go creating duplicated validatedPassword
again.
Thanks Lantua for detailed answer. I was trying something else with code then forgot to remove duplicate