Асинхронный JSON-запрос в Swift - PullRequest
0 голосов
/ 03 января 2019

Я хотел бы рандомизировать выпуск с рандомизированными вопросами из полученного JSON. Поэтому я должен «загрузить» его асинхронно.

************ Вопрос отредактированный ************************

Почему Массив не "заполнен"? Также .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()
    }

}

Область отладки:

 [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 Ответ

0 голосов
/ 03 января 2019

Причина в том, что dataTask сама асинхронна.

Если вы хотите выполнить print("main.async") после возврата запроса, вам нужно добавить фрагмент в конце обработчика ответа.Как то так:

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