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 of Publishers. You can not just refer to it as CombineLatest, you need to say Publishers.CombineLatest.
- You need to check what type signature you function actually have. Even if the function is named
combineLatest, it doesn't actually return CombineLatest (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 a projectedValue of Published. If you're confused about the Published, you can try asking again in a new thread. Since the wrappedValue is String, the projectedValue, hence Self, is Published<Value>.Publisher.
- The first argument is of type
P, so the it should match the type of $passwordAgain which is Published<String>.Publisher.
- The
transform closure takes both Output of the publishers, and produce T, so T should be String? since our closure returns String?.
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.