Swift 中的异步 JSON 请求
Asynchronous JSON request in Swift
我想用收到的 JSON 中的随机问题随机分配一个出口。因此我必须异步地 "load" 它。
************问题已编辑************************
为什么数组不是 "filled"?还有 .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
原因是因为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()
)
我想用收到的 JSON 中的随机问题随机分配一个出口。因此我必须异步地 "load" 它。
************问题已编辑************************
为什么数组不是 "filled"?还有 .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
原因是因为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()
)