Completion Handler 不适用于 API 请求

问题描述 投票:0回答:1

我的代码执行 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")
            }
        })
swift google-maps uikit google-maps-markers
1个回答
0
投票

关于网络代码的事情是,因为你没有采用

async/await
,你的其他代码不会在网络发生时不暂停。因此,您的所有代码在网络甚至有机会开始之前就已完成。这导致了“乱序”的抱怨——因为使用网络和异步代码,事情do发生乱序。

你需要 every 这个事件链中的方法有一个完成处理程序。所以:

  • session.dataTask
    有一个完成处理程序,您已经实现了它。到目前为止,一切都很好。

  • performRequest
    必须有一个完成处理程序,当我们从网络请求返回时,它会在
    session.dataTask
    的完成处理程序中调用。

  • fetchPoi
    必须有一个完成处理程序,它从
    performRequest
    调用完成处理程序。

  • loadDataFromApi
    然后在
    fetchPoi
    .

    的完成处理程序中调用其完成处理程序

(不明白为什么,看http://www.programmingios.net/what-asynchronous-means/开头的三篇文章

但是一个更简单的解决方案将在整个过程中采用

async/await

© www.soinside.com 2019 - 2024. All rights reserved.