如果可能,我需要在后台运行此代码。我得到一个有时需要一段时间加载的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,但我没有运气。
答案 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()
}