我的代码执行 API 请求并加载数据。在下一步中,数据将在地图上显示为标记。但现在它的顺序是错误的。我的控制台首先显示
"Second line of code executed"
,然后是"The Data has been loaded"
。结果是 POI 不会显示在我的地图上。
这就是我下载和解析数据的方式:
struct hereApi {
static var dataFromHereApi = [Items]()
static var gewählteKategorie = 0
func fetchPoi(geoCordinate: String) {
var selectedCategory = "0"
selectedCategory = {
switch hereApi.gewählteKategorie {
case 0:
return
"gym"
case 1:
return "school"
default:
return "cinema"
}
}()
let urlString = "https://..."
performRequest(urlString: urlString)
}
func performRequest(urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { data, response, error in
if error != nil {
print(error!)
return
}
if let safeData = data {
parseJSON(poiData: safeData)
}
}
task.resume()
}
}
func parseJSON(poiData: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(POIData.self, from: poiData)
hereApi.dataFromHereApi = decodedData.items
print("The Data has been loaded.")
} catch {
print(error)
}
}
}
这就是我在另一个 ViewController 中执行请求的方式:
var networkGoogleApiConnect = hereApi()
func loadDataFromApi(arg: Bool, completion: (Bool) -> ()) {
...
networkGoogleApiConnect.fetchPoi(geoCordinate: fullCordinate)
completion(arg)
}
loadDataFromApi(arg: true, completion: { (success) -> Void in
print("Second line of code executed")
if success {
print("true")
} else {
print("false")
}
})
关于网络代码的事情是,因为你没有采用
async/await
,你的其他代码不会在网络发生时不暂停。因此,您的所有代码在网络甚至有机会开始之前就已完成。这导致了“乱序”的抱怨——因为使用网络和异步代码,事情do发生乱序。
你需要 every 这个事件链中的方法有一个完成处理程序。所以:
session.dataTask
有一个完成处理程序,您已经实现了它。到目前为止,一切都很好。
performRequest
必须有一个完成处理程序,当我们从网络请求返回时,它会在 session.dataTask
的完成处理程序中调用。
fetchPoi
必须有一个完成处理程序,它从 performRequest
调用完成处理程序。
loadDataFromApi
然后在fetchPoi
.的完成处理程序中调用其完成处理程序
(不明白为什么,看http://www.programmingios.net/what-asynchronous-means/开头的三篇文章)
但是一个更简单的解决方案将在整个过程中采用
async/await
。