Reputation: 27
Hi I am new to swift and currently learning json and APIs by playing with API from cryptocompare in Playground, rate limit for seconds is 15 per second, I am not getting the desired amount of return in my loop
this is my code
func getPrice(coinSymbol: String, currency: String, day: Date,
completion: @escaping (Double?) -> Void) {
let baseURL = URL(string: "https://min-api.cryptocompare.com/data/dayAvg")!
let query: [String: String] = ["fsym": coinSymbol, "tsym": currency, "toTs": String(format:"%.0f", day.timeIntervalSince1970)]
let url = baseURL.withQueries(query)!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data,
let rawJSON = try? JSONSerialization.jsonObject(with: data), //convert data into native swift values
let json = rawJSON as? [String: Any]{
if let price = json[currency] as? Double {
completion(price)
} else {
print("price not found")
}
} else {
print("Either no data was returned or data was not serialised.")
return
}
}
task.resume()
}
//lastMonth is an Array, [Date] with count of 31
for day in lastMonth {
getPrice(coinSymbol: "BTC", currency: "USD", day: day) { (price) in
if let price = price {
print(price)
}
}
}
this is my return in Playground
6738.16
6253.38
6346.16
6588.89
6705.49
.
.
.
price not found
price not found
8248.19
price not found
price not found
price not found
price not found
price not found
7572.14
7406.26
6998.43
7151.93
6993.97
Everytime it refreshes it prints different number of price but seldom do I get my desired 31 price. Is there anyway for me to make sure my function print the exact amount of price consistently in this loop?
Thanks alot
Upvotes: 1
Views: 1365
Reputation: 149
When I run this code in the playground in some request I get the following JSON response:
["MaxLimits": {
Hour = 8000;
Minute = 300;
Second = 15;
}, "Message": Rate limit excedeed!, "Data": <__NSArray0 0x60400000d680>(
)
, "Aggregated": 0, "YourCalls": {
hour = {
Histo = 489;
};
minute = {
Histo = 16;
};
second = {
Histo = 16;
};
}, "Type": 99, "Response": Error].
Even though I put a sleep of five seconds after each call. But when I run it in a project the code is executing correctly and I receive a valid response for each day. Maybe a playground error?
Upvotes: 0
Reputation: 17882
Your playground finishes executing after the for-loop, and does not wait for all asynchronous requests to return. You need to wait for them manually, like so:
let group = DispatchGroup()
for day in lastMonth {
group.enter()
getPrice(coinSymbol: "BTC", currency: "USD", day: day) { (price) in
if let price = price {
print(price)
}
group.leave()
}
}
group.notify(queue: DispatchQueue.main) {
print("done")
exit(0)
}
dispatchMain()
Upvotes: 4