• save imageData to firebase storage
  • new Bindable for isRegistering
  • completion for error

여러 곳에서 접근할 수 있도록 registeringHUD를 전역변수로 선언한다.

let registeringHUD = JGProgressHUD(style: .dark)

@objc fileprivate func handleRegister() {
  ...
}

After creating a new user, put imageData to ref , ref is firebase storage’s uuidString way something ImageData should be jpegData

  1. Create a new user
  2. Make a ref for an imageData
  3. Put a imageData on ref
  4. Retrieving download url of imageData
@objc fileprivate func handleRegister() {
        print("Register our User in Firebase Auth")
        guard let email = emailTextField.text else { return }
        guard let password = passwordTextField.text else { return }
        
        registeringHUD.textLabel.text = "Register"
        registeringHUD.show(in: view)
        
        Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
            if let err = err {
                print(err)
                self.showHUDWithError(error: err)
                return
            }
            
            print("Successfully registered user : ", res?.user.uid ?? "")
            
            // Only upload images to Firebase Storage once you are authorized
            let filename = UUID().uuidString
            let ref = Storage.storage().reference(withPath: "/images/\(filename)")
            let imageData = self.registrationViewModel.bindableImage.value?.jpegData(compressionQuality: 0.75) ?? Data()
            ref.putData(imageData, metadata: nil, completion: { (_, err) in
                
                if let err = err {
                    self.showHUDWithError(error: err)
                    return // bail
                }
                
                print("Finished uploading image to storage")
            })
        }
    }

Issue #2

Error Domain=FIRStorageErrorDomain Code=13000

I should have set firebase storage activate on firebase website first!!!

                print("Finished uploading image to storage")
                ref.downloadURL(completion: { (url, err) in
                    if let err = err {
                        self.showHUDWithError(error: err)
                        return
                    }
                    
                    self.registeringHUD.dismiss()
                    print("Download url of our image is :", url?.absoluteString ?? "")
                })
// output
Register our User in Firebase Auth
Successfully registered user :  5REBqkemTARJBT48jqKw8YCnyVL2
Finished uploading image to storage
Download url of our image is : https://firebasestorage.googleapis.com/v0/b/tinderswipematchfirestor-afc99.appspot.com/o/images%2F3469B19E-C737-49B0-A370-E65EC2E67E58?alt=media&token=0bfbdc68-8595-4f6d-8234-2bfb803121eb

Refactoring! for reactive programming

Controller always should be clean

So let’s make a Bindable<Bool> property on viewModel

var bindableIsRegisterating = Bindable<Bool>()

setupViewModelObserver for a new bindable property

// setupRegistrationViewModelObservers()
        registrationViewModel.bindableIsRegisterating.bind { [unowned self] (isRegistering) in
            if isRegistering == true {
                self.registeringHUD.textLabel.text = "Register"
                self.registeringHUD.show(in: self.view)
            } else {
                self.registeringHUD.dismiss()
            }
        }

keep tracking isRegisterating

@objc fileprivate func handleRegister() {
  ...
  registrationViewModel.bindableIsRegisterating.value = true
  ...
}

새로운 함수를 RegistrationViewModel에 만들어서 관리하고 싶다. Controller에 너무 많은 코드가 존재 Controller의 imageData 전송 process 함수들을 ViewModel로 가져온다.

func performRegistration(completion: (Error?) -> ()) {
        guard let email = email, let password = password else { return }
  
        Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
            
            if let err = err {
                print(err)
                self.showHUDWithError(error: err)
                return
            }
            
            print("Successfully registered user : ", res?.user.uid ?? "")
            
            // Only upload images to Firebase Storage once you are authorized
            let filename = UUID().uuidString
            let ref = Storage.storage().reference(withPath: "/images/\(filename)")
            let imageData = self.registrationViewModel.bindableImage.value?.jpegData(compressionQuality: 0.75) ?? Data()
            ref.putData(imageData, metadata: nil, completion: { (_, err) in
                
                if let err = err {
                    self.showHUDWithError(error: err)
                    return // bail
                }
                
                print("Finished uploading image to storage")
                ref.downloadURL(completion: { (url, err) in
                    if let err = err {
                        self.showHUDWithError(error: err)
                        return
                    }
                    
                    self.registrationViewModel.bindableIsRegisterating.value = false
                    print("Download url of our image is :", url?.absoluteString ?? "")
                    // stroe the download url into Firestore next lesson
                })
            })
        }
    }

performRegistration + completion: () -> () 으로 만든 후에 optional binding을 guard로 해준다(상단)

throw err with completion

            if let err = err {
                completion(err)
                return
            }

Closure use of non-escaping parameter ‘completion’ may allow it to escape, Parameter ‘completion’ is implicitly non-escaping

func performRegistration(completion: @escaping (Error?) -> ())

A type representing an error value that can be thrown.

@escaping 추가

    @objc fileprivate func handleRegister() {
        self.handleTapDismiss()
        
        registrationViewModel.bindableIsRegisterating.value = true
        registrationViewModel.performRegistration { [weak self] (err) in
            if let err = err {
                self?.showHUDWithError(error: err)
                return
            }
            
            print("Finished registering")
        }
    }

handleRegister() 함수에서 handleTapDismiss()도 실행해준다 (섬세한 움직임), registrationViewModel.performRegistration 함수의 completion을 여기서 구현해준다.

So, handleRegister() function get much cleaner than before!

why weak self?

태그: ,

카테고리:

업데이트:

댓글남기기