Missing argument for parameter 'user' in call SwiftUI

元气小坏坏 提交于 2021-02-05 12:32:47

问题


Please help, it is driving me nuts. I have a constant in ProfileViewModel (let user: UserModel) The UserModel is Identifiable in UserModel file I also initiate the user: UserModel in ProfileViewModel.

In HomeView I added the (let profileVM: ProfileViewModel) constant This allows me to retrieve a user profile image through "profileVM.user.profileImageURL.

In my MainView I load the HomeView() based on being logged in or not I am asked to pass the profileVM and user let constants within HomeView() giving me an error to run the App.

Please see my code:

MainView.Swift (this is where I am asked for the arguments)

    import UIKit
import SwiftUI
import Firebase

struct MainView: View {
    @EnvironmentObject var authViewModel: AuthViewModel
    @AppStorage("current_status") var profileRegistered = false
    
        
    var body: some View {

        ZStack{
            
            if authViewModel.session != nil && authViewModel.profileRegistered == false {
                RegisterView()
            } else {
                
                HomeView()
            }
           
            if authViewModel.session == nil {
                
                NavigationView{
                    
                    Login()
                        .navigationBarHidden(true)
                        .navigationBarBackButtonHidden(true)
                }
                
            }
    
            
            
            }
        }
    }

HomeView.swift (just the top)

import SwiftUI
import Firebase
import Kingfisher


struct HomeView: View {
    @State var showProfile: Bool = false
    @State var userSearch: Bool = false
    @EnvironmentObject var authViewModel: AuthViewModel
    let profileVM: ProfileViewModel
        
    var body: some View {
        VStack {
            HStack(alignment: .top) {
                //BUTTON TO SHOW FOLLOWER SCREEN AND FIND PEOPLE IN THE COMMUNITY
                Button(action: { self.userSearch.toggle() }) {
                    
                    Image(systemName: "person.crop.circle.badge.plus")
                        .font(.system(size: 30))
                        .foregroundColor(.black)
                    
                }.fullScreenCover(isPresented: $userSearch) {
                    UserSearch()}
                
                Spacer()
                //BUTTON TO OPEN UP PROFILE 
                Button(action: { self.showProfile.toggle() }) {
                    
                     KFImage(URL(string: profileVM.user.profileImageURL))
                        .renderingMode(.original)
                        .resizable()
                        .frame(width: 36, height: 36)
                        .clipShape(Circle())
                    
                }.fullScreenCover(isPresented: $showProfile) {
                    MyProfileView()}
                
            }
            .padding(.horizontal)
            .padding(.top, 15)
            
            Button(action: {
                // logging out...
               authViewModel.signOut()
                
            }, label: {
                Text("LogOut")
                    .fontWeight(.heavy)
            })
            
            Spacer()
    }
}

}



    
var body: some View {

ProfileViewModel.swift

    import SwiftUI

class ProfileViewModel: ObservableObject {
    // MARK: - @PROPERTIES
    //∆..............................
    @Published var isFollowed: Bool = false
    let user: UserModel
    //∆..............................
    
    // MARK: -∆ Initializer
    ///∆.................................
    init(user: UserModel) {
        self.user = user
        /// ∆ Will persist if following or not even when you close the app
        checkIfUserIsFollowed()
    }
    ///∆.................................
    
    ///∆ ........... Class Methods ...........
    
    // MARK: -∆  follow •••••••••
    func follow() -> Void {
        //∆..........
        /// ∆ The current user logged in ID
        guard let currentUid = FIREBASE_AUTH.currentUser?.uid else { return }
        let followingRef = COLLECTION_FOLLOWING_FIRESTORE.document(currentUid).collection("user-following")
        let followersRef = COLLECTION_FOLLOWERS_FIRESTORE.document(currentUid).collection("user-followers")
        
        /// ∆ Updates the following structure when following someone
        followingRef.document(user.id).setData([ : ]) { _ in
            //∆..........
            /// ∆ Updates the followers structure when following someone with the currentUid
            followersRef.document(currentUid).setData([ : ]) { _ in
                //∆..........
                self.isFollowed = true
                print("DEBUG: Followed: @\(self.user.lastname)...")
            }
        }
    }/// ∆ END OF: follow
    
    // MARK: -∆  unFollow •••••••••
    func unFollow() -> Void {
        //∆..........
        /// ∆ The current user logged in ID
        guard let currentUid = FIREBASE_AUTH.currentUser?.uid else { return }
        let followingRef = COLLECTION_FOLLOWING_FIRESTORE.document(currentUid).collection("user-following")
        let followersRef = COLLECTION_FOLLOWERS_FIRESTORE.document(currentUid).collection("user-followers")
        
        followingRef.document(user.id).delete { _ in
            //∆..........
            followersRef.document(currentUid).delete { _ in
                //∆..........
                self.isFollowed = false
                print("DEBUG: UnFollowed: @\(self.user.lastname)...")
            }
        }
    }/// ∆ END OF: unFollow
}
//∆.....................................................

extension ProfileViewModel {
    
    // MARK: -∆  checkIfUserIsFollowed •••••••••
    func checkIfUserIsFollowed() -> Void {
        //∆..........
        guard let currentUid = FIREBASE_AUTH.currentUser?.uid else { return }
        let followingRef = COLLECTION_FOLLOWING_FIRESTORE.document(currentUid).collection("user-following")
        
        followingRef.document(user.id).getDocument { snapShot, _ in
            //∆..........
            guard let isFollowed = snapShot?.exists else { return }
            self.isFollowed = isFollowed
        }
    }
}

UserModel.swift

import SwiftUI
import Firebase

struct UserModel: Identifiable {
    // MARK: - ∆@PROPERTIES
    //∆..............................
    var id = UUID().uuidString
    let headline: String
    let profileImageURL: String
    let firstname: String
    let lastname: String
    let email: String
    let bio: String
    var isCurrentUser: Bool {
        Auth.auth().currentUser?.uid == self.id
    }
    //∆..............................
    
    //∆.....................................................
    
    ///∆ ........... Initializer ...........
    init(dictionary: [String : Any]) {
        typealias k = RegistrationKeys
        //∆..........
        id = dictionary[k.uidKey] as? String ?? ""
        headline = dictionary[k.headline] as? String ?? ""
        profileImageURL = dictionary[k.profileImageURLKey] as? String ?? ""
        firstname = dictionary[k.firstname] as? String ?? ""
        lastname = dictionary[k.lastname] as? String ?? ""
        email = dictionary[k.emailKey] as? String ?? ""
        bio = dictionary[k.bioKey] as? String ?? ""
    }
}

RegistrationKeys.swift

import Foundation

struct RegistrationKeys: Hashable {
    
    static let emailKey = "email"
    static let headline = "headline"
    static let firstname = "firstname"
    static let lastname = "lastname"
    static let profileImageURLKey = "profileImageURL"
    static let bioKey = "bio"
    static let uidKey = "uid"
}

Registration function that uses the UserModel data to store in Firebase

 // MARK: -∆  registerUser •••••••••
    func registerUser(firstname: String, lastname: String, headline: String, bio: String, profileImage: UIImage) -> Void {
        //∆..........
        // MARK: -∆ (1) Upload Image •••••••••
        guard let imageData = profileImage.jpegData(compressionQuality: 0.3) else { return }
        /// ∆ Unique identifier for the image being uploaded
        let filename = NSUUID().uuidString
        
        let storageRef = Storage.storage().reference().child(filename)
        
        storageRef.putData(imageData, metadata: nil) { _, error in
            //∆..........
            if let error = error {
                print("\nDEBUG: {!!!} [ERROR] Failed to upload image: \(error.localizedDescription) {!!!}")
                return
            }
            
            /// ∆ Should print out before user is created
            print("DEBUG: Successfully uploaded user photo...")
            
            /// ∆ Accessing the image `URL` &
            storageRef.downloadURL { url, _ in
                //∆..........
                guard let profileImageURL = url?.absoluteString else { return }
                                
                let uid = FIREBASE_AUTH.currentUser!.uid
                    
                    // MARK: -∆ (4) Creating our document dictionary with keys & values •••••••••
                    typealias k = RegistrationKeys
                let data: [String : String] = [
                        k.uidKey: uid,
                        k.headline : headline,
                        k.firstname : firstname,
                        k.lastname : lastname,
                        k.bioKey : bio,
                        k.profileImageURLKey : profileImageURL
                    ]
                
                self.uploadCollectionToFirestore(
                    data: data,
                    uid: uid,
                    firstname: firstname,
                    lastname: lastname,
                    headline: headline,
                    bio: bio)
                    
                withAnimation{self.profileRegistered = true}
                }// ∆ END createUser into firebase
            }// ∆ END storageRef.downloadURL
        
        
        
    }
    
    
    
}/// ∆ END OF: RegisterView  Class
    
    extension AuthViewModel {
        
        
    
    // MARK: -∆ ••••••••• registerUser •••••••••
    fileprivate func uploadCollectionToFirestore(data: [String : String], uid: String,
                                                 firstname: String, lastname: String, headline: String,
                                                 bio: String) {
        
        isLoading = true
        //∆..........
        COLLECTION_USERS_FIRESTORE.document(uid).setData(data) { (err) in
           
            if err != nil{
                self.isLoading = false
                return
            }

            print("DEBUG: Successfully signed up user\n")
            
        }
    }

回答1:


HomeView as written demands a ProfileViewModel:

let profileVM: ProfileViewModel

MainView as written instantiates HomeView, but doesn't provide that object. Xcode is complaining, perhaps in an ambiguous way without a helpful autocomplete suggestion.

HomeView()

To create a ProfileViewModel, you must provide it a UserModel according to the init you have coded.

init(user: UserModel) {
        self.user = user
        /// ∆ Will persist if following or not even when you close the app
        checkIfUserIsFollowed()
    }

So, in MainView, you need to know how to make the correct UserModel or provide some sort of default case that will trigger some reaction.

Based on the comment in the code, you have a persistence service that will spit that user data out for you.

HomeView(profileVM: ProfileVM(user: userObjectFromPersistence)


来源:https://stackoverflow.com/questions/65720362/missing-argument-for-parameter-user-in-call-swiftui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!