diff --git a/SwiftUIBasics.xcodeproj/xcuserdata/trumann.xcuserdatad/xcschemes/xcschememanagement.plist b/SwiftUIBasics.xcodeproj/xcuserdata/trumann.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..27cd9e4
--- /dev/null
+++ b/SwiftUIBasics.xcodeproj/xcuserdata/trumann.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..3809ecf 100644
--- a/SwiftUIBasics/Views/SignUpView.swift
+++ b/SwiftUIBasics/Views/SignUpView.swift
@@ -16,9 +16,21 @@ class SignUpViewModel: ObservableObject {
// outputs
@Published var isValidUsernameLength: Bool = false
+
@Published var isValidPasswordLength: Bool = false
+
@Published var isValidPasswordUpperCase: Bool = false
+
+ @Published var isValidPasswordLowerCase: Bool = false
+
+ @Published var isValidPasswordHasNumber: Bool = false
+
+ @Published var isValidPasswordHasSpecialCharacter: Bool = false
+
+
+
@Published var isValidPasswordMatch: Bool = false
+
@Published var isValid: Bool = false
private var cancelableSet: Set = []
@@ -27,7 +39,12 @@ class SignUpViewModel: ObservableObject {
$username
.receive(on: RunLoop.main)
.map { username in
- return username.count >= 4
+ let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
+ if let _ = username.range(of: pattern, options: .regularExpression) {
+ return true
+ } else {
+ return false
+ }
}
.assign(to: \.isValidUsernameLength, on: self)
.store(in: &cancelableSet)
@@ -52,6 +69,57 @@ class SignUpViewModel: ObservableObject {
}
.assign(to: \.isValidPasswordUpperCase, on: self)
.store(in: &cancelableSet)
+
+ $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)
+
+ $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: \.isValidPasswordHasNumber, on: self)
+ .store(in: &cancelableSet)
+
+ $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: \.isValidPasswordHasSpecialCharacter, on: self)
+ .store(in: &cancelableSet)
+
+ $passwordConfirm
+ .receive(on: RunLoop.main)
+ .map{
+ passwordConfirm in
+ return self.password == passwordConfirm
+ }
+ .assign(to: \.isValidPasswordMatch, on: self)
+ .store(in: &cancelableSet)
Publishers.CombineLatest($password, $passwordConfirm)
.receive(on: RunLoop.main)
@@ -80,15 +148,27 @@ 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: "e-mail", value: $vm.username)
+ .autocorrectionDisabled()
+ .textInputAutocapitalization(.never)
+ .keyboardType(.emailAddress)
+
+ RequirementText(text: "This field should be an email", isValid: vm.isValidUsernameLength)
.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: "One special character", isValid: vm.isValidPasswordHasSpecialCharacter)
+ RequirementText(text: "At least one number", isValid: vm.isValidPasswordHasNumber)
+
}
.padding()
+
+
FormTextField(name: "Confirm Password", value: $vm.passwordConfirm, isSecure: true)
RequirementText(text: "Your confirm password should be the same as password", isValid: vm.isValidPasswordMatch)
.padding()