Rates.swift (1517B)
1 // 2 // Rates.swift 3 // lightninglink 4 // 5 // Created by William Casarin on 2022-03-24. 6 // 7 8 import Foundation 9 10 enum Currency: String { 11 case USD 12 case CAD 13 } 14 15 enum StringNum: Decodable { 16 case string(String) 17 case number(Double) 18 19 init (from decoder: Decoder) throws { 20 let value = try decoder.singleValueContainer() 21 if let str = try? value.decode(String.self) { 22 self = .string(str) 23 return 24 } 25 26 self = .number(try value.decode(Double.self)) 27 } 28 } 29 30 struct ExchangeRate { 31 let currency: Currency 32 let rate: Double 33 } 34 35 func get_exchange_rate(for_cur: Currency, cb: @escaping (ExchangeRate?) -> ()) { 36 let url = URL(string: "https://api-pub.bitfinex.com/v2/tickers?symbols=tBTC\(for_cur)")! 37 let task = URLSession.shared.dataTask(with: url) { (mdata, response, error) in 38 guard let data = mdata else { 39 cb(nil) 40 return 41 } 42 43 guard let rate = decode_bitfinex_exchange_rate(data) else { 44 cb(nil) 45 return 46 } 47 48 cb(ExchangeRate(currency: for_cur, rate: rate)) 49 } 50 51 task.resume() 52 } 53 54 func decode_bitfinex_exchange_rate(_ data: Data) -> Double? { 55 guard let container: Array<Array<StringNum>> = decode_data(data) else { 56 return nil 57 } 58 59 guard container.count >= 1 && container[0].count >= 2 else { 60 return nil 61 } 62 63 switch container[0][1] { 64 case .string: 65 return nil 66 case .number(let xr): 67 return Double(xr) 68 } 69 } 70