From 94c38654dfb916337314f6d831abd696372c2c30 Mon Sep 17 00:00:00 2001 From: romystark Date: Fri, 26 Jan 2024 17:21:38 -0600 Subject: [PATCH] SolveSignupview --- .../UserInterfaceState.xcuserstate | Bin 0 -> 13621 bytes .../xcschemes/xcschememanagement.plist | 14 +++ SwiftUIBasics/Views/SignUpView.swift | 103 +++++++++++++++--- 3 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 SwiftUIBasics.xcodeproj/project.xcworkspace/xcuserdata/romark17.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 SwiftUIBasics.xcodeproj/xcuserdata/romark17.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/SwiftUIBasics.xcodeproj/project.xcworkspace/xcuserdata/romark17.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftUIBasics.xcodeproj/project.xcworkspace/xcuserdata/romark17.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..c35cf2a4c53744b73ff2063d34da3684bc734a33 GIT binary patch literal 13621 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 Wr&f#M3V~Zv{-2~${0{w1o&H~3{WV(v literal 0 HcmV?d00001 diff --git a/SwiftUIBasics.xcodeproj/xcuserdata/romark17.xcuserdatad/xcschemes/xcschememanagement.plist b/SwiftUIBasics.xcodeproj/xcuserdata/romark17.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..27cd9e4 --- /dev/null +++ b/SwiftUIBasics.xcodeproj/xcuserdata/romark17.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + SwiftUIBasics.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/SwiftUIBasics/Views/SignUpView.swift b/SwiftUIBasics/Views/SignUpView.swift index 6cef5d9..d4fc6db 100644 --- a/SwiftUIBasics/Views/SignUpView.swift +++ b/SwiftUIBasics/Views/SignUpView.swift @@ -1,16 +1,11 @@ -// -// SignUpView.swift -// SwiftUIBasics -// -// Created by Diplomado on 09/12/23. -// - import SwiftUI import Combine class SignUpViewModel: ObservableObject { // inputs @Published var username: String = "" + @Published var mail: String = "" + @Published var password: String = "" @Published var passwordConfirm: String = "" @@ -18,20 +13,41 @@ class SignUpViewModel: ObservableObject { @Published var isValidUsernameLength: Bool = false @Published var isValidPasswordLength: Bool = false @Published var isValidPasswordUpperCase: Bool = false + + @Published var isValidMail: Bool = false + + @Published var isValidPasswordLowerCase: Bool = false + @Published var isValidPasswordHasASymbol: Bool = false + @Published var isValidPasswordHasANumber: Bool = false + + + + @Published var isValidPasswordMatch: Bool = false @Published var isValid: Bool = false private var cancelableSet: Set = [] init() { - $username +// $username +// .receive(on: RunLoop.main) +// .map { username in +// return username.count >= 4 +// } +// .assign(to: \.isValidUsernameLength, on: self) +// .store(in: &cancelableSet) + + $mail .receive(on: RunLoop.main) - .map { username in - return username.count >= 4 + .map { mail in + let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" + let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx) + return emailPred.evaluate(with: mail) } - .assign(to: \.isValidUsernameLength, on: self) + .assign(to: \.isValidMail, on: self) .store(in: &cancelableSet) + $password .receive(on: RunLoop.main) .map { password in @@ -40,10 +56,11 @@ class SignUpViewModel: ObservableObject { .assign(to: \.isValidPasswordLength, on: self) .store(in: &cancelableSet) + // isValidPasswordUpperCase $password .receive(on: RunLoop.main) .map { password in - let pattern = "[A-Z]" + let pattern = "[A-Z]+" if let _ = password.range(of: pattern, options: .regularExpression) { return true } else { @@ -52,6 +69,50 @@ class SignUpViewModel: ObservableObject { } .assign(to: \.isValidPasswordUpperCase, on: self) .store(in: &cancelableSet) + + // isValidPasswordLowerCase + $password + .receive(on: RunLoop.main) + .map { password in + let pattern = "[a-z]" + if let _ = password.range(of: pattern, options: .regularExpression) { + return true + } else { + return false + } + } + .assign(to: \.isValidPasswordLowerCase, on: self) + .store(in: &cancelableSet) + + // isValidPasswordHasASymbol + $password + .receive(on: RunLoop.main) + .map { password in + let pattern = "[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]" + if let _ = password.range(of: pattern, options: .regularExpression) { + return true + } else { + return false + } + } + .assign(to: \.isValidPasswordHasASymbol, on: self) + .store(in: &cancelableSet) + + // isValidPasswordHasANumber + $password + .receive(on: RunLoop.main) + .map { password in + let pattern = "[0-9]+" + if let _ = password.range(of: pattern, options: .regularExpression) { + return true + } else { + return false + } + } + .assign(to: \.isValidPasswordHasANumber, on: self) + .store(in: &cancelableSet) + + Publishers.CombineLatest($password, $passwordConfirm) .receive(on: RunLoop.main) @@ -80,13 +141,26 @@ struct SignUpView: View { .bold() .foregroundStyle(.maryBlue) .padding(.bottom, 30) - FormTextField(name: "Username", value: $vm.username) - RequirementText(text: "A minimum of 4 characters", isValid: vm.isValidUsernameLength) + +// FormTextField(name: "Username", value: $vm.username) +// RequirementText(text: "A minimum of 4 characters", isValid: vm.isValidUsernameLength) +// .padding() + + FormTextField(name: "Mail", value: $vm.mail) + .keyboardType(.emailAddress) + + + RequirementText(text: "Must be a valid mail", isValid: vm.isValidMail) .padding() + FormTextField(name: "Password", value: $vm.password, isSecure: true) VStack { RequirementText(text: "A minimum of 8 characters", isValid: vm.isValidPasswordLength) RequirementText(text: "One uppercase letter", isValid: vm.isValidPasswordUpperCase) + RequirementText(text: "One lowercase letter", isValid: vm.isValidPasswordLowerCase) + RequirementText(text: "At least one symbol", isValid: vm.isValidPasswordHasASymbol) + RequirementText(text: "At least one number", isValid: vm.isValidPasswordHasANumber) + } .padding() FormTextField(name: "Confirm Password", value: $vm.passwordConfirm, isSecure: true) @@ -132,3 +206,4 @@ struct SignUpView: View { #Preview { SignUpView() } +