Howdy folks, hoping this is the right place for this. Fairly new to Xcode and swift. I've resolved all of my error but the one stated in the title. This (should be ) the last error until a successful build. Was told beginner questions welcome so here goes it.
Important Specs:
Mac mini M1
Xcode Version 12.5.1 (12E507)
Mac OS 12.0 Beta (21A5284e)
Background: I am trying to use Firebase SDK framework (installing from a GIT repo via swift package manager. All went well. Followed a guide where a guy had created a UI app with Firebase Auth however he used pods (I stayed away from pods as researching installing pods for a M1 device (every single forum gave VERY different methods) I just scrapped the pods for now.
Anyways In my Target swift file I am calling ContentView like so
I know my naming scheme is not correct I'd just like to get a successful build and then go back and fix all of the names. (Author of guide did not post his project )
Appreciate any help ! If there is anything I can upload to help please let me know.
I suspect it is with one of the /@EnvironmentObject/ instances.
import SwiftUI
import Firebase
@main
struct SwiftUILoginApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
let ViewModel = AppViewModel
ContentView() -->Type 'AppViewModel.Type' cannot conform to 'ObservableObject'
.environmentObject(ViewModel)
Of course I have read several forums where that specific error message may be misleading (ugh)
So here is the ObservableObject from the contentview swift file.
(This is all from a guide so any questions as to why it is done a certain way I do not know)
content file:
import SwiftUI
import FirebaseAuth
class AppViewModel: ObservableObject {
let auth = Auth.auth()
@Published var SignedIn = false
var isSignedIn: Bool {
return auth.currentUser != nil
}
func SignIn (email: String, pswd: String){
auth.signIn(withEmail: email, password: pswd) { [weak self ]result, error in
guard result != nil, error == nil else {
return
}
DispatchQueue.main.sync {
self?.SignedIn = true
}
}
}
func SignUp (email: String, pswd: String){
auth.createUser(withEmail: email, password: pswd) { [weak self] result, error in
guard result != nil, error == nil else {
return
}
DispatchQueue.main.sync {
self?.SignedIn = true
}
}
}
func Signout() {
try? auth.signOut()
self.SignedIn = false
}
}
struct ContentView: View {
@EnvironmentObject var viewModel: AppViewModel
var body: some View {
NavigationView {
if viewModel.SignedIn {
VStack{
Text("You are signed in")
Button(action: {
viewModel.Signout()
}, label: {
Text("Sign Out")
.background(Color.green)
.foregroundColor(/*@START_MENU_TOKEN@*/.blue/*@END_MENU_TOKEN@*/)
.frame(width: 200, height: 50, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.padding()
})
}
}
else {
SigninView()
}
}
.onAppear {
viewModel.SignedIn = viewModel.isSignedIn
}
}
struct SigninView: View {
@State var email = ""
@State var pswd = ""
@EnvironmentObject var viewModel: AppViewModel
var body: some View{
VStack {
Image("logo")
.resizable()
.scaledToFit()
.frame(width: 500, height: 500)
VStack{
TextField("Email Address", text: $email)
.disableAutocorrection(true)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.padding()
.frame(width: 400.0, height: 50.0)
.background(Color(.secondarySystemBackground))
SecureField("Password", text: $pswd)
.disableAutocorrection(true)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.padding(/*@END_MENU_TOKEN@*/)
.frame(width: 400.0, height: 50.0)
.background(Color(.secondarySystemBackground))
Button(action: {
guard !email.isEmpty,!pswd.isEmpty else {
return
}
viewModel.SignIn(email: email, pswd: pswd)
}, label: {
Text("Sign In")
.padding()
.frame(width: 200.0, height: 50.0)
.background(Color.blue)
.cornerRadius(20.0)
})
}
.padding()
Spacer()
}
.navigationTitle("Sign In")
}
}
}
struct SignUpView: View {
@State var email = ""
@State var pswd = ""
@EnvironmentObject var viewModel: AppViewModel
var body: some View{
VStack {
Image("logo")
.resizable()
.scaledToFit()
.frame(width: 500, height: 500)
VStack{
TextField("Email Address", text: $email)
.disableAutocorrection(true)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.padding()
.frame(width: 400.0, height: 50.0)
.background(Color(.secondarySystemBackground))
SecureField("Password", text: $pswd)
.disableAutocorrection(true)
.autocapitalization(/*@START_MENU_TOKEN@*/.none/*@END_MENU_TOKEN@*/)
.padding(/*@END_MENU_TOKEN@*/)
.frame(width: 400.0, height: 50.0)
.background(Color(.secondarySystemBackground))
Button(action: {
guard !email.isEmpty, !pswd.isEmpty else {
return
}
viewModel.SignUp(email: email, pswd: pswd)
}, label: {
Text("Create Account")
.padding()
.frame(width: 200.0, height: 50.0)
.background(Color.blue)
.cornerRadius(20.0)
})
NavigationLink("Create Account", destination: SignUpView())
}
.padding()
Spacer()
}
.navigationTitle("Create Account")
}
}
struct ContentView_Previews: PreviewProvider{
static var previews: some View{
ContentView()
// .preferredColorScheme(.dark)
}
}