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 0000000..c35cf2a
Binary files /dev/null and b/SwiftUIBasics.xcodeproj/project.xcworkspace/xcuserdata/romark17.xcuserdatad/UserInterfaceState.xcuserstate differ
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()
}
+