在后台运行JSON请求Swift 4

时间:2018-04-27 01:47:44

标签: ios json swift

如果可能,我需要在后台运行此代码。我得到一个有时需要一段时间加载的JSON请求(滞后在URL的服务器端,而不是代码本身。)

如果可能,我想在后台运行以下代码。有什么想法吗?

        var stockData: Data!
        var concatTickersString = ""


        for object in dataArray.reversed() {

            concatTickersString = concatTickersString + "," + object.symbol

        }

        let url = URL(string: "https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols=" + concatTickersString + "&apikey=IX58FUCXKD695JY0")

        do {
            stockData = try Data(contentsOf: url!)

            let json = try JSON(data: stockData)

            if let jsonArray = json["Stock Quotes"].array {

                for ticker in jsonArray.reversed() {

                    if(jsonArray.count != 0){

                        let stockTicker = ticker["1. symbol"].string!
                        let stockPrice = ticker["2. price"].string!

                        self.watchListArray.append(WatchlistData(tickerName: stockTicker, tickerPrice: Double(stockPrice)?.currency))

                    }

                }


                tableView.isHidden = false

            }


        } catch {
            print(error)     
        }

它是JSON的服务器需要很长时间我不认为它必然是数据(内容)

我尝试使用dispatch_async,但我没有运气。

1 个答案:

答案 0 :(得分:3)

滞后是由Data(contentsOf:)是同步方法引起的。正如the documentation所说,

  

重要

     

请勿使用此同步方法来请求基于网络的网址。对于基于网络的URL,此方法可以在慢速网络上阻止当前线程数十秒,从而导致用户体验不佳,而在iOS中,可能会导致应用程序被终止。   相反,对于非文件URL,请考虑使用URLSession类的dataTask(with:completionHandler :)方法。有关示例,请参阅Fetching Website Data into Memory

正如您通过实验发现的那样,将此方法放在DispatchQueue.main.async中并不会使其异步。而是按照文档的说明进行操作。

这是在Fetching Website Data into Memory找到的略微修改的示例:

func startLoad() {
    let url = URL(string: "https://www.example.com/")!
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            self.handleClientError(error)
            return
        }
        guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
            self.handleServerError(response)
            return
        }
        if let data = data,
            let string = String(data: data, encoding: .utf8) {
            DispatchQueue.main.async {
                doSomething(with: string)
            }
        }
    }
    task.resume()
}