I'm making an app in Swift that connects to a web service. I want to make requests, such as login. After logging in, I want to navigate to HomeView but never switch.
I have these files:
` MainView:
struct MainView: View { @ObservedObject var viewModel = MainViewViewModel()
var body: some View {
if viewModel.savedStudent != nil {
HomeView()
} else {
LoginView()
}
}
} `
MainViewViewModel:
` class MainViewViewModel: ObservableObject { @Published var savedStudent: Student?
init() {
loadSavedStudent()
}
func loadSavedStudent() {
if let savedStudentData = UserDefaults.standard.data(forKey: "student") {
if let savedStudent = try? JSONDecoder().decode(Student.self, from: savedStudentData) {
self.savedStudent = savedStudent
} else {
print("Error al decodificar el estudiante.")
}
} else {
print("No existe ningun estudiante logueado.")
}
}
} `
` LoginViewViewModel:
class APIFetchHandler: ObservableObject {
@Published var legajo = ""
@Published var password = ""
@Published var errorMessage = ""
static let sharedInstance = APIFetchHandler()
func postAPIData() {
guard self.validate() else {
return
}
let url = "https://webservice.frvm.utn.edu.ar/autogestion/login";
let headers: HTTPHeaders = [
"nick": legajo,
"password": password
]
AF.request(url, method: .post, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseData { response in
switch response.result {
case .success(let data):
do {
// GUARDA EL ESTUDIANTE EN UserDefaults
let student = try JSONDecoder().decode(Student.self, from: data)
if let encodedStudent = try? JSONEncoder().encode(student) {
UserDefaults.standard.set(encodedStudent, forKey: "student")
UserDefaults.standard.synchronize()
print("Student saved to UserDefaults")
self.errorMessage = ""
} else {
print("Error encoding student object")
}
// PRINTEAR UserDefaults PARA VER SI SE GUARDO CORRECTAMENTE
if let savedStudentData = UserDefaults.standard.data(forKey: "student") {
if let savedStudent = try? JSONDecoder().decode(Student.self, from: savedStudentData) {
print(savedStudent)
} else {
print("Error decoding student object")
}
} else {
print("No student data found in UserDefaults")
}
} catch {
if let statusCode = response.response?.statusCode, statusCode == 401 {
print("Credenciales incorrectas.")
self.errorMessage = "Legajo/Contraseña incorrectos."
}
return
}
case .failure(let error):
print("------------ ERROR ------------")
print(error)
print("------------ ERROR ------------")
}
}
}
private func validate() -> Bool {
guard !legajo.trimmingCharacters(in: .whitespaces).isEmpty,
!password.trimmingCharacters(in: .whitespaces).isEmpty else {
self.errorMessage = "Llenar todos los campos, por favor."
return false
}
return true
}
} `
` LoginView:
struct LoginView: View {
@StateObject var viewModel = APIFetchHandler()
var body: some View {
VStack {
Text("UTN - FRVM")
.font(.title)
Text("Iniciar sesión")
Form {
if !viewModel.errorMessage.isEmpty {
Text(viewModel.errorMessage)
.foregroundStyle(.red)
}
TextField("Legajo", text: $viewModel.legajo)
.textFieldStyle(DefaultTextFieldStyle())
SecureField("Password", text: $viewModel.password)
.textFieldStyle(DefaultTextFieldStyle())
Button {
viewModel.postAPIData()
} label: {
ZStack {
RoundedRectangle(cornerRadius: 10)
Text("Iniciar sesión")
.foregroundColor(.white)
.bold()
}
}
.padding()
}
}
}
}`