0

I would like to randomize an outlet with randomized questions from a received JSON. Therefore I have to "load" it asynchronously.

************Question edited************************

Why is the Array not "filled"? Also the .count = 0.

@IBAction func refreshBtnTapped(_ sender: UIBarButtonItem) {

    let queue = DispatchQueue(label: "Json loading", qos: .userInteractive)

    self.btnOutlet.isEnabled = false

    func jsonDataRequest () {
        let url = "https://redaktion.pflegonaut.de/service.php"
        let urlObj = URL(string: url)
        URLSession.shared.dataTask(with: urlObj!) { (data, response, error) in
            do {

                // Json to Array
                self.questionsJsonVar = try JSONDecoder().decode([Question].self, from: data!)
                let countOfQuestions = self.questionsJsonVar.count
                print(self.questionsJsonVar)

                // MARK:-- later in queue
                DispatchQueue.main.async {

                    print("main.async")

                    // -- Randomize Question Outlet
                    print("Anzahl der Fragen" , self.countOfQuestions)
// PROBLEM prints "Anzahl der Fragen 0"    
                    let randNumber = Int.random(in: 1 ... self.countOfQuestions)
// PROBLEM therefore upperbound < lowerbound
                    print(self.questionsJsonVar[0].Frage)
// PROBLEM not filled
                    self.questionTextOutlet.text = self.questionsJsonVar[self.randNumber].Frage
// PROBLEM does not work
                }

            } catch {
                print(error)
            }
            }.resume()
    }

    //MARK:-- first in queue
    queue.async {
        jsonDataRequest()
    }

}

Debug Area:

 [R***.Question(ID: "1", Frage: "1", Antwort1: "2", Antwort2: "3", Antwort3: "4", Antwort4: "5", Correct: "1", Notiz: Optional("  1234"), LernsektorID: "0", LerneinheitID: "1", LernbereichID: "1", SchwierigkeitID: "1"),
 R***.Question (ID: "51", Frage: " Welche der drei genannten Werte steuert den Atemantrieb?", Antwort1: "pO2", Antwort2: "pCO2", Antwort3: "pH", Antwort4: "K+", Correct: "2", Notiz: Optional("   Gesteuert wird die Atmung im wesentlichen durch das Gehirn beziehungsweise das Atemzentrum in der Medulla oblongata. Ausschlaggebend ist dabei die Reaktion von Chemorezeptoren auf den Kohlendioxid-Gehalt..."),
 ...
 ...]
 main.async
 Anzahl der Fragen 0

1 Answer 1

1

The reason is because the dataTask is asynchronous itself.

If you want to execute the print("main.async") after the request has returned you need to add the snippet at the end of the response handler. Something like this:

func jsonDataRequest () {
    let url = "https://redaktion.pflegonaut.de/service.php"
    let urlObj = URL(string: url)
    URLSession.shared.dataTask(with: urlObj!) { (data, response, error) in
        do {

            // Json to Array
            self.questionsJsonVar = try JSONDecoder().decode([Question].self, from: data!)
            let countOfQuestions = self.questionsJsonVar.count
            print(self.questionsJsonVar)

            // Logic after response has arrived
            DispatchQueue.main.async {
                print("main.async")
            }
        } catch {
                print(error)
        }
    }.resume()
)
Sign up to request clarification or add additional context in comments.

2 Comments

works! Thanks. I wanted to update the UI on Dispatch.Queue.main.async (change Label.text to a randomized Json property), but that is not working. "Index out of range". Therefore I think the Array is not "filled".
the var questionJsonVar: [Question] = [] was declared in the superclass QuizVC: UIViewController

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.