我目前正在尝试使用BEMSimpleLineGraph在swift中创建历史汇率图表,并使用AlomoFire从http://fixer.io/获取数据。我正在使用for循环来循环7天(只是为了看看我是否可以使它正常工作)然后将值附加到(或称为任何名称)数组到一个名为xAxisData的数组
func updateGraphData(timeInterval: Int){
if selectedCurrency1 != nil && selectedCurrency2 != nil { // checking if both currencies have been selected
self.xAxisData.removeAll() // removing some default values
for i in 1...timeInterval { // don't know exactly if i'm doing this the optimal way?
print("passed")
let date = Date()
let dateComponents = Calendar.current.dateComponents([.month, .day,.year], from: date) //getting the the year(again, just to see if it's working)
historyURL = "http://api.fixer.io/\(dateComponents.year!.description)-03-0\(String(i))?base=\(selectedCurrency1!.rawValue)" //modifying the url to my needs
Alamofire.request(historyURL, method: .get).responseJSON { // requesting data
response in
if response.result.isSuccess{
let json = JSON(response.result.value!)
self.xAxisData.append(json["rates"] [self.selectedCurrency2!.rawValue].doubleValue) // using SwiftyJSON btw to convert, but shouldn't this in theory append in the correct order?
print(json["date"].stringValue) // printing out the date
}
else{
print("Error \(String(describing: response.result.error))")
}
}
}
}
}
CONSOLE:
[]
2017-03-02
2017-03-03
2017-03-01
2017-03-03
2017-03-03
2017-03-06
2017-03-07
[4.5359999999999996, 4.5316000000000001, 4.4739000000000004, 4.5316000000000001, 4.5316000000000001, 4.5133000000000001, 4.4844999999999997]
我知道我错误地将货币价值变为双倍,因为它可能应该是一个浮动货币。如果需要,请随时提出更多信息,或以任何其他方式纠正我,因为我只是想学习。
我希望输出按时间顺序排列,因此日期为1,2,3,4,5,6,7而不是2,3,1,3,3,6,7。我正在使用多个已修改的网址,例如api.fixer.io/2017-03-01?base=GB。
答案 0 :(得分:1)
问题是所有网络请求都是异步的,并且无法保证它们将按照调用的顺序完成执行。因此,数组中的数据不是您调用请求的顺序。
您可以使用序列DispatchQueue
按照您调用它们的顺序运行请求,但这会使您的程序变慢,因为它一次只执行一个请求而不是运行所有他们并行。
针对此特定问题的更好解决方案是将完成处理程序内部的值插入到某个索引中,而不是仅仅附加它们。这样,即使您不必同步API调用,也可以使订单与API调用的顺序相同。或者,您可以将返回的值存储在字典中,其中键是您发出网络请求的日期的字符串表示形式。
答案 1 :(得分:0)
创建一个结构例如
struct Rate {
let currency : String
let date : Date
var value : Double
}
创建数组var historicalRates = [Rate]()
。
在for
循环
使用Calendar
API计算日期,您的方式在下个月溢出时遇到麻烦。例如
let calendar = Calendar.current
// set the date to noon to avoid daylight saving changes at midnight in a few countries
let today = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: Date())!
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
for dayOffset in 0...7 {
let currentDate = calendar.date(byAdding: .day, value: dayOffset, to: today)!
let currentDateAsString = formatter.string(from: currentDate)
print(currentDate, currentDateAsString)
}
从当前日期创建Date
。
Rate
实例,将其添加到historicalRates
并将其传递给异步任务。value
。DispatchGroup
在循环结束时收到通知。historicalRates
排序date
。