Rev 9 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
//// LoginView.swift// twogetskills//// Created by Efrain Yanez Recanatini on 1/27/22.//import SwiftUIimport AudioToolboximport Networkimport Alamofireimport SwiftyJSONimport SafariServicesimport RNCryptorstruct SigninView: View {@Environment(\.openURL) var openURL@EnvironmentObject var appNavigation : AppNavigation@State var keyboardHeight : CGFloat = 0private let appData = AppData.sharedInstance@State private var email: String = "efrain.yanez@leaderslinked.com" {didSet {if email.count > 250 {email = String(email.prefix(250))AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }}}}@State private var isValidEmail : Bool = true@State private var isEditingEmail : Bool = false@State private var password: String = "Cesa2020$" {didSet {if password.count > 25 {password = String(password.prefix(25))AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }}}}@State private var isValidPassword : Bool = true@State private var isEditingPassword : Bool = false@State private var isPasswordShow: Bool = false@State private var goToMain : Bool = false@State private var showProgressView : Bool = false@State private var presentAlert : Bool = false@State private var titleAlert : String = ""@State private var messageAlert : String = ""var body: some View {ZStack {Color("color_window_background").edgesIgnoringSafeArea(.all)VStack(spacing: 0) {HeaderGroupView()EmailTextFieldGroup(email: self.$email, isEditingEmail: self.$isEditingEmail, isValidEmail: self.$isValidEmail, password: self.$password, isEditingPassword: self.$isEditingPassword, isValidPassword: self.$isValidPassword)PasswordTextFieldGroup(password: self.$password,isEditingPassword: self.$isEditingPassword,isValidPassword: self.$isValidPassword,isPasswordShow: self.$isPasswordShow).padding(.top, isValidEmail ? 10 : 2)Button(action: {if(validate()) {signin()}}, label: {Text(Config.LANG_SIGNIN_BUTTON_SIGNIN).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).frame(width: UIScreen.main.bounds.width - 32, height: 35).foregroundColor(Color("color_button_foreground")).background(Color("color_button_background")).border(Color("color_button_border"), width: Config.BUTTON_BORDER_SIZE).cornerRadius(Config.BUTTON_BORDER_RADIUS)}).padding(.top, 16).padding(.leading, 16).padding(.trailing, 16)ButtonSignUpGroup()Spacer()ButtonForgotPasswordGroup()}}//}.offset(y : CGFloat(-(self.keyboardHeight / 2))).onAppear {/*NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { (notification) inlet keyboardHeight: CGFloat = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height ?? 0self.keyboardHeight = keyboardHeightprint("keyboardHeightShow = \(keyboardHeight)")}*/NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { (notification) inprint("keyboardHeightHide ")}}.alert(isPresented: $presentAlert) {Alert(title: Text(self.titleAlert),message: Text(self.messageAlert),dismissButton: .default(Text("Ok")))}}private func signin() -> Void{self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)if !self.isValidEmail || !self.isValidPassword {return}let device_uuid = appData.deviceUuidprint("signin")print(" aes = \(appData.aes) " )print(" email = \(self.email) " )print(" password = \(self.password) " )let syncDao = SyncDao.sharedInstanceif appData.aes.isEmpty {let syncRecord = syncDao.selectOneByType(type: Constants.SYNC_ADAPTER_TYPE_DEVICE)if syncRecord.id > 0 {let syncAdapter = SyncAdapter()syncAdapter.sync {success in}}self.titleAlert = Config.LANG_ERROR_DEVICE_NOT_REGISTER_TITLEself.messageAlert = Config.LANG_ERROR_DEVICE_NOT_REGISTER_MESSAGEself.presentAlert = truereturn}self.showProgressView = true;let emailData = email.data(using: .utf8)!let emailCipherData = RNCryptor.encrypt(data: emailData, withPassword: appData.aes)let emailEncrypted = emailCipherData.base64EncodedString()let passwordData = password.data(using: .utf8)!let passwordCipherData = RNCryptor.encrypt(data: passwordData, withPassword: appData.aes)let passwordEncrypted = passwordCipherData.base64EncodedString()print(" email encrypted = \(emailEncrypted) " )print(" password encrypted = \(passwordEncrypted) " )let parameters = [Constants.POST_SIGNIN_FIELD_APPLICATION_ID: "\(Constants.GLOBAL_APPLICATION_ID)",Constants.POST_SYNC_FIELD_DEVICE_UUID: device_uuid,Constants.POST_SIGNIN_FIELD_EMAIL: emailEncrypted,Constants.POST_SIGNIN_FIELD_PASSWORD: passwordEncrypted,Constants.POST_SIGNIN_FIELD_ENCRYPTER: Constants.GLOBAL_ENCRYPTER]let headers: HTTPHeaders = [.accept(Constants.HTTP_HEADER_ACCEPT)]print("URL signin : \(Config.URL_SIGNIN)")self.showProgressView = trueAF.request(Config.URL_SIGNIN, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{(response) inself.showProgressView = falseswitch response.result {case .success:let json = try? JSON(data: response.data!)print("json : \(json)")if json?["success"] ?? "" != false {let dataService = DataService()if dataService.syncFromServer(json : json) {let now = Date()let dateFormatter = DateFormatter()dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICElet dateOn = dateFormatter.string(from: now)var userLog = UserLogModel()userLog.userUuid = appData.userUuiduserLog.activity = Constants.USER_LOG_ACTIVITY_SIGNINuserLog.addedOn = dateOnlet userLogDao = UserLogDao.sharedInstanceuserLogDao.insert(record: userLog)var sync = SyncModel()var json = userLog.toJson()json[Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME] = Constants.SYNC_ADAPTER_DATA_TYPE_USER_LOGsync = SyncModel();sync.type = Constants.SYNC_ADAPTER_TYPE_SYNCif let theJSONData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),let data = String(data: theJSONData, encoding: String.Encoding.ascii) {sync.data = data}syncDao.insert(record : sync);appNavigation.pageActive = AppMainPage.home//self.goToMain = true}} else {let message = json?["data"].string ?? ""if !message.isEmpty {self.titleAlert = Config.LANG_ERROR_GENERIC_TITLEself.messageAlert = messageself.presentAlert = true}}returncase .failure :self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLEself.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGEself.presentAlert = truereturn}/*switch response.result {case .success:print("Response Data : \(response.data!) ")let json = try? JSON(data: response.data!)if json?["success"] ?? "" != false {let dataService = DataService()if dataService.syncFromServer(json : json) {self.goToMain = true}} else {let message = json?["data"].string ?? ""if !message.isEmpty {self.titleAlert = "Error"self.messageAlert = messageself.presentAlert = true}}returncase .failure:self.titleAlert = "Servidor no encontrado"self.messageAlert = "Ocurrio un error de comunicación"self.presentAlert = truereturn}*/}}private func validate() -> Bool{print("validate - email : \(email)")print("validate - password : \(password)")if email.isEmpty {self.isValidEmail = false} else if !checkEmail(email: email) {self.isValidEmail = false} else {self.isValidEmail = true}if password.isEmpty {self.isValidPassword = false} else if(!checkPassword(password: password)) {self.isValidPassword = false} else {self.isValidPassword = true}return self.isValidEmail && self.isValidPassword}private func checkEmail(email : String) -> Bool {let regex = #"^[a-zA-Z0-9_\-\.~]{2,}@[a-zA-Z0-9_\-\.~]{2,}\.[a-zA-Z]{2,}$"#let predicate = NSPredicate(format: "SELF MATCHES %@", regex)return predicate.evaluate(with: email) ? true : false;}private func checkPassword(password : String) -> Bool {let regexOld = #"^(?=.*\d+)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,16}$"#let regexNew = #"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\#\?\!\@\$\^\%\*\-]).{6,16}$"#let predicateNew = NSPredicate(format: "SELF MATCHES %@", regexNew)let predicateOld = NSPredicate(format: "SELF MATCHES %@", regexOld)if(predicateOld.evaluate(with: password)) {return true} else if(predicateNew.evaluate(with: password)) {return true} else {return false}}}struct SigninView_Previews: PreviewProvider {static var previews: some View {SigninView()}}struct HeaderGroupView: View {var body: some View {//Inicio LogoHStack {Image("logo").resizable().frame(width: 50, height: 50)Text(Config.LANG_SIGNIN_APP_NAME).font(Font.custom(Config.FONT_NAME_BOLD, size: 24)).foregroundColor(Color("color_textview"))Spacer()}.padding(.leading, 16).padding(.top, 66)//Fin logo//Inicio SaludoHStack {Text(Config.LANG_SIGNIN_GREATING).font(Font.custom(Config.FONT_NAME_BOLD, size: 32)).foregroundColor(Color("color_textview"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Saludo//Inicio EncabezadoHStack {Text(Config.LANG_SIGNIN_HEAD_LINE1).font(Font.custom(Config.FONT_NAME_REGULAR, size: 16)).foregroundColor(Color("color_textview"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Encabezado}}struct EmailTextFieldGroup : View {@Binding var email: String@Binding var isEditingEmail : Bool@Binding var isValidEmail : Bool@Binding var password: String@Binding var isEditingPassword: Bool@Binding var isValidPassword: Boolvar body : some View {//Inicio Label EmailHStack {Text(Config.LANG_SIGNIN_TITLE_EMAIL_FIELD).font(Font.custom(Config .FONT_NAME_REGULAR, size: 11)).foregroundColor(Color("color_textview"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Label Email//Inicio TextField EmailGroup {HStack {/*Image("ui_mail").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)*/TextField("",text: self.$email,onEditingChanged: { (changed) inif changed {if self.isEditingPassword {self.isValidPassword = Validator.checkPassword(password: self.password)self.isEditingPassword = false}self.isEditingEmail = true} else {self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)}}, onCommit: {self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)}).font(Font.custom(Config.FONT_NAME_REGULAR, size: 12)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.emailAddress).autocapitalization(.none)//.foregroundColor(Color("color_textfield_foreground"))//.background(Color("color_textfield_background")).padding(.leading, 4)Spacer()}}.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background")).overlay(RoundedRectangle(cornerRadius: 5).stroke(Color(self.isEditingEmail ? "color_textfield_border_active" : self.isValidEmail ? "color_textfield_border" : "color_textfield_border_error" ))).padding(.leading, 16).padding(.trailing, 16).padding(.top, self.isValidEmail ? 10 : 2)if !self.isValidEmail {HStack {Spacer()Text(Config.LANG_SIGNIN_ERROR_EMAIL_FIELD).foregroundColor(.red).font(Font.custom(Config.FONT_NAME_REGULAR, size: 11))}.padding(.top, 5).padding(.trailing, 16)}//Fin TextField Email}}struct PasswordTextFieldGroup : View {@Binding var password: String@Binding var isEditingPassword: Bool@Binding var isValidPassword: Bool@Binding var isPasswordShow: Boolvar body : some View {//Inicio Label PasswordHStack {Text(Config.LANG_SIGNIN_TITLE_PASSWORD_FIELD).font(Font.custom(Config .FONT_NAME_REGULAR, size: 11)).foregroundColor(Color("color_textview"))Spacer()}.padding(.leading, 16)//Fin Label Password//Inicio TextField PasswordGroup {HStack {/*Image("ui_key").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)*/if isPasswordShow {TextField("",text: self.$password,onEditingChanged: { (changed) inif changed {self.isEditingPassword = true} else {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}}, onCommit: {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}).font(Font.custom(Config.FONT_NAME_REGULAR, size: 12)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.default).autocapitalization(.none)/*.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background"))*/.padding(.leading, 4)Spacer()Button(action: {self.isPasswordShow.toggle()}, label: {Image("ui_visibility_off").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)})} else {SecureField("", text: self.$password, onCommit: {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}).onHover { hovering inif hovering {print("onHover")} else {print("offHover")}}.onTapGesture {self.isEditingPassword = true}.font(Font.custom(Config.FONT_NAME_REGULAR, size: 11)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.default).autocapitalization(.none)/*.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background"))*/.padding(.leading, 4)Spacer()Button(action: {self.isPasswordShow.toggle()}, label: {Image("ui_visibility").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)})}////ui_visibility}}.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background")).overlay(RoundedRectangle(cornerRadius: 5).stroke(Color(self.isEditingPassword ? "color_textfield_border_active" : self.isValidPassword ? "color_textfield_border" : "color_textfield_border_error" ))).padding(.leading, 16).padding(.trailing, 16).padding(.top, 2)if !self.isValidPassword {HStack {Spacer()Text(Config.LANG_SIGNIN_ERROR_PASSWORD_FIELD).foregroundColor(.red).font(Font.custom(Config.FONT_NAME_REGULAR, size: 11))}.padding(.top, 5).padding(.trailing, 16)}//Fin TextField Password}}struct ButtonSignUpGroup : View {@Environment(\.openURL) var openURLvar body : some View {Button(action: {openURL(URL(string: Config.URL_SIGNUP_ENDPOINT)!)}, label: {Text(Config.LANG_SIGNIN_BUTTON_SIGNUP).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).frame(width: UIScreen.main.bounds.width - 32, height: 35).foregroundColor(Color("color_button_foreground")).background(Color("color_button_background")).border(Color("color_button_border"), width: Config.BUTTON_BORDER_SIZE).cornerRadius(Config.BUTTON_BORDER_RADIUS)}).padding(.top, 16).padding(.leading, 16).padding(.trailing, 16)}}struct ButtonForgotPasswordGroup : View {@Environment(\.openURL) var openURLvar body : some View {Button(action: {openURL(URL(string: Config.URL_FORGOT_PASSWORD_ENDPOINT)!)}, label: {Text(Config.LANG_SIGNIN_BUTTON_FORGOT_PASSWORD).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).foregroundColor(Color("color_button_foreground"))}).padding(.vertical, 16)}}