0

I have a UIViewController with an optional string variable. I do some fetch on my Firebase database and the fetching function has a completion block. In the completion block I do some work and I want to set the class variable based on the work I've done in the completion block.

My problem is that the Firebase call async so when I use the class variable somewhere else in my ViewController its still nil. So how can I wait for the firebase call to end, show a progress indicator and then continue?

This is how my code looks like now:

class QuizSettingsViewController: UIViewController {

    private var code: String? = nil
    
    public func createSettingsModel() -> [String: Any]? {
    guard let name = testNameTextField.text, let timeToComplete = completionTimeTextField.text, let timeToCompleteInt = Int(timeToComplete) else {
        return nil }
    
    generateCodeForNewTest()
    
    print(self.code) //nil
    
    if let code = code {
        let quizSettings = ["name": name, "code": code, "quizDescription": descriptionTextView.text.description, "timeToComplete": timeToCompleteInt, "allowARMode": allowARModeCheckBox.on, "allowViewCompletedTest": allowViewCompletedTestCheckbox.on] as [String: Any]
        
        return quizSettings
    }
    
    return nil
}

private func generateCodeForNewTest() {
    QuizService.shared.fetchAllQuizzes { [weak self] quizzes, error in
        guard let strongSelf = self else { return }
        if let error = error {
            AlertManager.showQuizError(on: strongSelf, with: "Error Generating Code", and: error.localizedDescription)
            return
        }
        
        if let quizzes = quizzes {
            
            var codesInUse = [String]()
            
            for quiz in quizzes {
                let code = quiz.code
                codesInUse.append(code)
            }
            
            let chars = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
            
            while true {
                var code = ""
                for _ in 1...12 {
                    code.append(chars.randomElement() ?? "A")
                }
                
                code.insert("-", at: code.index(code.startIndex, offsetBy: 6))
                
                if !codesInUse.contains(code) {
                    strongSelf.code = code
                    print(strongSelf.code) //Optional("FALN02-YA4ZXO")
                    break
                }
            }
        }
    }
}
pistifeju
  • 95
  • 8

0 Answers0