Last active
July 30, 2023 18:08
-
-
Save gokhanakkurt/916ebfc8aaab36c6f37c1f9e16795dea to your computer and use it in GitHub Desktop.
Currency Converter in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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