Skip to content

Instantly share code, notes, and snippets.

@gokhanakkurt
Last active July 30, 2023 18:08
Show Gist options
  • Save gokhanakkurt/916ebfc8aaab36c6f37c1f9e16795dea to your computer and use it in GitHub Desktop.
Save gokhanakkurt/916ebfc8aaab36c6f37c1f9e16795dea to your computer and use it in GitHub Desktop.
Currency Converter in Swift
struct ServiceResources {
static let exchangeUri = "https://api.exchangeratesapi.io/latest"
}
enum Currency: String {
case euro = "EUR"
case pound = "GBP"
case dollar = "USD"
case turkishLira = "TRY"
}
struct ExchangeResult: Codable {
let base: String
let date: String
let rates: [String: Double]
enum CodingKeys: String, CodingKey {
case base = "base"
case date = "date"
case rates = "rates"
}
}
protocol ExchangeServiceProtocol {
typealias Handler = (Result<ExchangeResult, Error>) -> Void
func getExchangeRate(from: Currency, to: Currency, handler: @escaping Handler)
}
class ExchangeService: ExchangeServiceProtocol {
func getExchangeRate(from base: Currency, to: Currency, handler: @escaping Handler) {
guard let url = URL(string: String(format:"%@?base=%@", ServiceResources.exchangeUri, base.rawValue)) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let anError = error {
handler(.failure(anError))
}else{
if let res = data{
do {
let rate = try JSONDecoder().decode(ExchangeResult.self, from: res)
handler(.success(rate))
} catch {
handler(.failure(error))
}
}
}
}
task.resume()
}
}
protocol ConverterProtocol {
func convert(amount: Double, currency: Currency, into another: Currency)
func calculate(for amount: Double, withRate: Double) -> Double
}
class CurrencyConverter: ConverterProtocol {
private let service: ExchangeService
private let onConverted: (_ result: Double?, _ error: Error?) -> Void
init(service: ExchangeService, onConverted: @escaping (_ result: Double?, _ error: Error?) -> Void){
self.service = service
self.onConverted = onConverted
}
func convert(amount: Double, currency: Currency, into another: Currency) {
self.service.getExchangeRate(from: currency, to: another) {[unowned self] (result) in
switch result {
case .failure(let error):
self.onConverted(nil, error)
case .success(let exchange):
let rate = exchange.rates.filter({$0.key == another.rawValue})
let result = self.calculate(for: amount, withRate: rate.values.first!)
self.onConverted(result, nil)
}
}
}
func calculate(for amount: Double, withRate: Double) -> Double {
return amount * withRate
}
}
let service = ExchangeService()
let converter = CurrencyConverter(service: service) { (value, error) in
if let anError = error {
print(anError.localizedDescription)
}
if let amount = value {
print("conversion result: \(amount)")
}
}
converter.convert(amount: 10.0, currency: .dollar, into: .turkishLira)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment