Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Data not being passed from View into ViewModel in Swift

I’m new to iOS development. I am learning about MVVM. I am trying to hook up my app to firebase for authentication. It seems like everything is working because it’s all building. BUT I force unwrapped the localized description error after I checked to see if it’s not nil, and I do infact have an error message of "Password must be 6 characters or more." and the test password I’m setting up is more than 6 characters, so I think the problem is that the information is not being captured from the MainView to the Viewmodel…?

Please look at my code and let me know.

I currently have 3 files:
SplashScreenView

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import SwiftUI

struct SplashScreenView: View {
    @State private var isActive = false
    @State private var size = 0.7
    @State private var opacity = 0.5
    
    var body: some View {
        
        if isActive {
            withAnimation{
                MainView().environmentObject(AuthViewModel())
            }
        } else {
            ZStack {
                RoundedRectangle(cornerRadius: 30, style: .continuous)
                    .foregroundStyle(LinearGradient(colors: [.orange, .red], startPoint: .topLeading, endPoint: .bottomTrailing))
                
                
                    .ignoresSafeArea()
                VStack {
                    VStack{
                        Image("logo")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 250)
                    }
                    .scaleEffect(size)
                    .opacity(opacity)
                    .onAppear(){
                        withAnimation(.easeIn(duration: 1.2)) {
                            self.size = 0.9
                            self.opacity = 1.0
                        }
                    }
                }.onAppear() {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
                        self.isActive = true
                    }
                }
            }
        }
    }
}

struct SplashView_Previews: PreviewProvider {
    static var previews: some View {
        SplashScreenView()
    }
}

MainView:

import SwiftUI
import Firebase

struct MainView: View {
    
    @State var email = ""
    @State var password = ""
    @EnvironmentObject var authModel:AuthViewModel
    
    var body: some View {
        ZStack {
            Color.theme.blue
            
            RoundedRectangle(cornerRadius: 30, style: .continuous)
                .foregroundStyle(LinearGradient(colors: [.orange, .red], startPoint: .topLeading, endPoint: .bottomTrailing))
                .frame(width: 1000, height: 450)
                .rotationEffect(.degrees(15))
                .offset(x: 20)
            
            VStack(spacing: 20) {
                
                Image("logo")
                    .resizable()
                    .scaledToFill()
                    .frame(width: 100)
                    .offset(y: 10)
                
                Text("Welcome")
                    .foregroundColor(.white)
                    .font(Font.custom("Poppins-Bold", size: 40))
                    .offset(y:-10)
                
                // Email TextField
                TextField("", text: $email)
                    .foregroundColor(.white)
                    .textFieldStyle(.plain)
                    .placeholder(when: email.isEmpty) {
                        Text("Email Address")
                            .foregroundColor(.white)
                            .font(Font.custom("Poppins-Light", size: 20))
                    }
                
                // Email TextBox
                Rectangle()
                    .frame(width:350, height: 1)
                    .foregroundColor(.white)
                    .padding(.top, -5)
                
                // Password TextField
                SecureField("", text: $password)
                    .foregroundColor(.white)
                    .textFieldStyle(.plain)
                    .placeholder(when: password.isEmpty) {
                        Text("Password")
                            .foregroundColor(.white)
                            .font(Font.custom("Poppins-Light", size: 20))
                    }
                
                // Password TextBox
                Rectangle()
                    .frame(width:350, height: 1)
                    .foregroundColor(.white)
                    .padding(.top, -5)
                
                Button {
                    authModel.register()
                } label: {
                    Text("Sign Up")
                        .frame(width: 200, height: 40)
                        .background(
                            .orange
//                            RoundedRectangle(cornerRadius: 10, style: .continuous)
//                                .fill(.linearGradient(colors: [.red, .orange], startPoint: .topTrailing, endPoint: .bottomTrailing))
                            )
                        .cornerRadius(10)
                        .foregroundColor(.black)
                        .font(Font.custom("Poppins-Medium", size: 18))
                }
                
                Spacer()
                Spacer()
                // Login Link
                HStack {
                    Text("Already Have An Account?")
                        .foregroundColor(.white)
                        .font(Font.custom("Poppins-Medium", size: 18))
                    Button {
                        authModel.login()
                    } label: {
                        Text("Login")
                            .foregroundColor(.orange)
                            .font(Font.custom("Poppins-Medium", size: 18))
                    }
                }.offset(y: 100)
                
                
                    
            }
            .frame(width: 350, height: 60)
        }.ignoresSafeArea()
    }
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        MainView().environmentObject(AuthViewModel())
    }
}

extension View {
    func placeholder<Content: View>(
        when shouldShow: Bool,
        alignment: Alignment = .leading,
        @ViewBuilder placeholder: () -> Content) -> some View {

        ZStack(alignment: alignment) {
            placeholder().opacity(shouldShow ? 1 : 0)
            self
        }
    }
}

and AuthViewModel:

import Foundation
import Firebase


class AuthViewModel: ObservableObject {
    
    
    func register() {
        Auth.auth().createUser(withEmail: MainView().email, password: MainView().password) { result, error in
            if error != nil {
                print(error!.localizedDescription)
            }
        }
    }
    
    func login() {
        Auth.auth().signIn(withEmail: MainView().email, password: MainView().password) { result, error in
            if error != nil {
                print(error!.localizedDescription)
            }
        }
    }
    
    
    
}

and for ‘auth view model’ before, I had had a @published var mainView = MainView() but I don’t think that’s right…if someone can please explain what I’m doing wrong, I’d REALLY appreciate it!!! I did search on here, but the other similar questions to mine was in C# or another language.

>Solution :

Every time you call MainView() you are creating a different instance, of the view, one does not know about the other.

class AuthViewModel: ObservableObject {
    func register(email: String, password: String)  {
        Auth.auth().createUser(withEmail: email, password: password) { result, error in
            if error != nil {
                print(error!.localizedDescription)
            }
        }
    }
    
    func login(email: String, password: String) {
        Auth.auth().signIn(withEmail: email, password: password) { result, error in
            if error != nil {
                print(error!.localizedDescription)
            }
        }
    }
}

Then use

authModel.register(email: email, password: password)

authModel.login(email: email, password: password)

Try the Apple SwiftUI Tutorials, if you don’t focus on the basics you will face an uphill battle.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading