为什么我的API调用失败

我有以下代码:

func convert(currencyToConvert:String,amount:Double,currencyToConvertTo:String,date:String)->Double{ makeConnection(date: date) usleep(80000) if let x = currencyRates[currencyToConvert]{ var a = 0.00 if currencyToConvert == "USD"{ a = amount*currencyRates["SGD"]! } else { a = (amount*currencyRates[currencyToConvertTo]!)/x } return a } else { print("currency not available") return 0.00 } } func makeConnection(date:String){ currencyRates.removeAll() let url = URL(string: "https://openexchangerates.org/api/historical/\(date).json?app_id=xyz") let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in if error != nil { print ("ERROR") // ADD SEVERAL URL'S HERE FOR ACCESS HERE } else { if let content = data { do { let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject if let rates = myJson["rates"] as? NSDictionary { for (key, value) in rates { self.currencyRates[(key as? String)!] = value as? Double } } } catch { } } } } task.resume() } 

有时,当我打电话给这个function时,打印出“货币不可用”),但其他时间通话的作品,它转换货币。 我可以做些什么来保证通话不会失败? 我甚至增加了一个延迟时间,以确保货币有足够的时间在拨打电话之前获取。

编辑1:

好吧,所以我删除了睡眠,并添加了一个while循环,但声明

 currency not available 

打印几乎200-300次之前执行这实际上导致应用程序崩溃在iPhone上。 我怎样才能使用其他方法达到类似的结果。

 func convert(currencyToConvert:String,amount:Double,currencyToConvertTo:String,date:String)->Double{ makeConnection(date: date) var currencyFetched:Bool = false var a:Double = 0.0 repeat { if let x = currencyRates[currencyToConvert]{ if currencyToConvert == "USD"{ a = amount*currencyRates["SGD"]! } else { a = (amount*currencyRates[currencyToConvertTo]!)/x } currencyFetched = true print("currency available") return a } else { print("currency not available") currencyFetched = false } }while currencyFetched == false } 

如上所述,线程睡眠不是一个好主意。 相反,你可以使用@escaping闭包。

 func convert(currencyToConvert:String ,amount:Double ,currencyToConvertTo:String ,date:String , completion: @escaping((Double?)->())){ currencyRates.removeAll() let url = URL(string: "https://openexchangerates.org/api/historical/\(date).json?app_id=xyz") let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in var result: Double? if let content = data { do { let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject if let rates = myJson["rates"] as? NSDictionary { for (key, value) in rates { self.currencyRates[(key as? String)!] = value as? Double } if let x = currencyRates[currencyToConvert]{ if currencyToConvert == "USD"{ result = amount*currencyRates["SGD"]! } else { result= (amount*currencyRates[currencyToConvertTo]!)/x } } } } catch { } } completion(result) } task.resume() } 

最后使用:

 convert(currencyToConvert: "",amount: 0.0,currencyToConvertTo: "",date:""){ value in if let value = value{ // Use it here } } 

让一个线程hibernate并不是一个好习惯,你最好把它移动到Api成功的部分之后,因为hibernate时间可能会完成,并且请求仍然是获取数据,所以数据是零,或者如果请求立即完成,它会一直等到睡眠时间结束,这将延迟显示数据给用户,这是不是一个好的用户体验