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
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()
)