Search code examples
iosswiftstructuiviewcontroller

How to call present code inside a struct in Swift


I try to alert when something went wrong but i try to create alert i get error like this :
Instance member 'present' of type 'UIViewController' cannot be used on instance of nested type 'SignUpViewController.FirebaseServices'

How can i alert my users without this my way? Or any solution about my problem? I think my problem is about Struct. Thank you!



import UIKit
import FirebaseAuth
import FirebaseFirestore
import FirebaseStorage

extension SignUpViewController {
 
    struct SignUpModelFirebase {
        
        let emailText : String
        let passwordText : String
        let nameText : String
        let usernameText : String
        let profileImage : UIImage
       
    }
    
    struct FirebaseServices {
        
        static func createUser(user : SignUpModelFirebase, completion: @escaping(Error?) -> Void) {
        
            let storage  = Storage.storage()
            let storageReference = storage.reference()
            let mediaFolder = storageReference.child("Profile Image")
            
            if let data = user.profileImage.jpegData(compressionQuality: 0.5) {
                
                let uuidImg = UUID().uuidString
            
                let imageReference = mediaFolder.child("\(uuidImg)")
                imageReference.putData(data) { storageMetaData, error in
                    
                    if let error = error {
                        
                        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: UIAlertController.Style.alert)
                        let action = UIAlertAction(title: "OK!", style: UIAlertAction.Style.default)
                        alert.addAction(action)
                        present(alert, animated: true)
                        print(error.localizedDescription)
                   
                    }else {
                        imageReference.downloadURL { url, error in
                            if let error = error {
                                print(error.localizedDescription)
                            }else {
                                guard let imageURL = url?.absoluteString else {return}
                                print(imageURL)
                                Auth.auth().createUser(withEmail: user.emailText, password: user.passwordText) { data, error in
                                    
                                    guard let uid = data?.user.uid else {return}
                                    
                                   let data = [
                                    
                                    "email" : user.emailText,
                                    "username" : user.usernameText,
                                    "name" : user.nameText,
                                    "profileImageUrl" : imageURL,
                                    "uid" : uid
     
                                   ] as [String : Any]
                                    let firestoreDatabase =  Firestore.firestore()
                                    firestoreDatabase.collection("Users").document(uid).setData(data,completion: completion)
                                    
                                }
                            }
                            
                        }
                    }
                }
                
            }      
        }
    }
}

Solution

  • You are going about this all wrong. Your FirebaseServices struct should not be performing any user interface actions. It should only perform some logic and get data or return an error.

    It is the caller (such as a view controller) of FirebaseServices that should handle the resulting data or error and update the UI as needed.

    Remove the alert code from FirebaseServices. Simply pass the error back through the createUser completion block to the caller. Let the caller determine how to handle the error. That may or may not be the display of an alert.