Rename SpotPrice* to Price*
This commit is contained in:
@@ -12,11 +12,11 @@ import Combine
|
||||
struct ContentView: View {
|
||||
@ObservedObject private var satsViewModel = SatsViewModel()
|
||||
|
||||
@State private var spotPriceSource: SpotPriceSource = .coinbase
|
||||
@State private var priceSource: PriceSource = .coinbase
|
||||
|
||||
private let dateFormatter = DateFormatter()
|
||||
|
||||
private let spotPriceFetcherDelegator = SpotPriceFetcherDelegator()
|
||||
private let priceFetcherDelegator = PriceFetcherDelegator()
|
||||
|
||||
init() {
|
||||
dateFormatter.dateStyle = .short
|
||||
@@ -26,7 +26,7 @@ struct ContentView: View {
|
||||
@MainActor
|
||||
func updatePrice() async {
|
||||
do {
|
||||
guard let price = try await spotPriceFetcherDelegator.btcToUsd() else {
|
||||
guard let price = try await priceFetcherDelegator.btcToUsd() else {
|
||||
satsViewModel.btcToUsdString = ""
|
||||
return
|
||||
}
|
||||
@@ -41,13 +41,13 @@ struct ContentView: View {
|
||||
var body: some View {
|
||||
Form {
|
||||
Section {
|
||||
Picker("Price Source", selection: $spotPriceSource) {
|
||||
ForEach(SpotPriceSource.allCases, id: \.self) {
|
||||
Picker("Price Source", selection: $priceSource) {
|
||||
ForEach(PriceSource.allCases, id: \.self) {
|
||||
Text($0.description)
|
||||
}
|
||||
}
|
||||
.onChange(of: spotPriceSource) { newSpotPriceSource in
|
||||
spotPriceFetcherDelegator.spotPriceSource = newSpotPriceSource
|
||||
.onChange(of: priceSource) { newPriceSource in
|
||||
priceFetcherDelegator.priceSource = newPriceSource
|
||||
Task {
|
||||
await updatePrice()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// CoinGeckoSpotPriceFetcher.swift
|
||||
// CoinGeckoPriceFetcher.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/19/24.
|
||||
@@ -8,29 +8,29 @@
|
||||
import Foundation
|
||||
import BigDecimal
|
||||
|
||||
private struct CoinGeckoSpotPriceResponse: Codable {
|
||||
let bitcoin: CoinGeckoSpotPrice
|
||||
private struct CoinGeckoPriceResponse: Codable {
|
||||
let bitcoin: CoinGeckoPrice
|
||||
}
|
||||
|
||||
private struct CoinGeckoSpotPrice: Codable {
|
||||
private struct CoinGeckoPrice: Codable {
|
||||
let usd: Decimal
|
||||
}
|
||||
|
||||
class CoinGeckoSpotPriceFetcher : SpotPriceFetcher {
|
||||
class CoinGeckoPriceFetcher : PriceFetcher {
|
||||
private static let urlString = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&precision=18"
|
||||
|
||||
func btcToUsd() async throws -> BigDecimal? {
|
||||
do {
|
||||
guard let urlComponents = URLComponents(string: CoinGeckoSpotPriceFetcher.urlString), let url = urlComponents.url else {
|
||||
guard let urlComponents = URLComponents(string: CoinGeckoPriceFetcher.urlString), let url = urlComponents.url else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let (data, _) = try await URLSession.shared.data(from: url, delegate: nil)
|
||||
|
||||
let spotPriceResponse = try JSONDecoder().decode(CoinGeckoSpotPriceResponse.self, from: data)
|
||||
let spotPrice = spotPriceResponse.bitcoin
|
||||
let priceResponse = try JSONDecoder().decode(CoinGeckoPriceResponse.self, from: data)
|
||||
let price = priceResponse.bitcoin
|
||||
|
||||
return BigDecimal(spotPrice.usd)
|
||||
return BigDecimal(price.usd)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// CoinbaseSpotPriceFetcher.swift
|
||||
// CoinbasePriceFetcher.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/19/24.
|
||||
@@ -8,37 +8,37 @@
|
||||
import Foundation
|
||||
import BigDecimal
|
||||
|
||||
private struct CoinbaseSpotPriceResponse: Codable {
|
||||
let data: CoinbaseSpotPrice
|
||||
private struct CoinbasePriceResponse: Codable {
|
||||
let data: CoinbasePrice
|
||||
}
|
||||
|
||||
private struct CoinbaseSpotPrice: Codable {
|
||||
private struct CoinbasePrice: Codable {
|
||||
let amount: String
|
||||
let base: String
|
||||
let currency: String
|
||||
}
|
||||
|
||||
class CoinbaseSpotPriceFetcher : SpotPriceFetcher {
|
||||
class CoinbasePriceFetcher : PriceFetcher {
|
||||
private static let urlString = "https://api.coinbase.com/v2/prices/BTC-USD/spot"
|
||||
private static let btc = "BTC"
|
||||
private static let usd = "USD"
|
||||
|
||||
func btcToUsd() async throws -> BigDecimal? {
|
||||
do {
|
||||
guard let urlComponents = URLComponents(string: CoinbaseSpotPriceFetcher.urlString), let url = urlComponents.url else {
|
||||
guard let urlComponents = URLComponents(string: CoinbasePriceFetcher.urlString), let url = urlComponents.url else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let (data, _) = try await URLSession.shared.data(from: url, delegate: nil)
|
||||
|
||||
let coinbaseSpotPriceResponse = try JSONDecoder().decode(CoinbaseSpotPriceResponse.self, from: data)
|
||||
let coinbaseSpotPrice = coinbaseSpotPriceResponse.data
|
||||
let coinbasePriceResponse = try JSONDecoder().decode(CoinbasePriceResponse.self, from: data)
|
||||
let coinbasePrice = coinbasePriceResponse.data
|
||||
|
||||
guard coinbaseSpotPrice.base == CoinbaseSpotPriceFetcher.btc && coinbaseSpotPrice.currency == CoinbaseSpotPriceFetcher.usd else {
|
||||
guard coinbasePrice.base == CoinbasePriceFetcher.btc && coinbasePrice.currency == CoinbasePriceFetcher.usd else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return BigDecimal(coinbaseSpotPrice.amount)
|
||||
return BigDecimal(coinbasePrice.amount)
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// SpotPriceFetcher.swift
|
||||
// PriceFetcher.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/19/24.
|
||||
@@ -8,6 +8,6 @@
|
||||
import Foundation
|
||||
import BigDecimal
|
||||
|
||||
protocol SpotPriceFetcher {
|
||||
protocol PriceFetcher {
|
||||
func btcToUsd() async throws -> BigDecimal?
|
||||
}
|
||||
29
SatsPrice/Network/PriceFetcherDelegator.swift
Normal file
29
SatsPrice/Network/PriceFetcherDelegator.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// PriceFetcherDelegator.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/20/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import BigDecimal
|
||||
|
||||
class PriceFetcherDelegator: PriceFetcher {
|
||||
private let coinbasePriceFetcher = CoinbasePriceFetcher()
|
||||
private let coinGeckoPriceFetcher = CoinGeckoPriceFetcher()
|
||||
|
||||
var priceSource: PriceSource = .coinbase
|
||||
|
||||
private var delegate: PriceFetcher {
|
||||
switch priceSource {
|
||||
case .coinbase:
|
||||
coinbasePriceFetcher
|
||||
case .coingecko:
|
||||
coinGeckoPriceFetcher
|
||||
}
|
||||
}
|
||||
|
||||
func btcToUsd() async throws -> BigDecimal? {
|
||||
return try await delegate.btcToUsd()
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
//
|
||||
// SpotPriceFetcherDelegator.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/20/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import BigDecimal
|
||||
|
||||
class SpotPriceFetcherDelegator: SpotPriceFetcher {
|
||||
private let coinbaseSpotPriceFetcher = CoinbaseSpotPriceFetcher()
|
||||
private let coinGeckoSpotPriceFetcher = CoinGeckoSpotPriceFetcher()
|
||||
|
||||
var spotPriceSource: SpotPriceSource = .coinbase
|
||||
|
||||
private var delegate: SpotPriceFetcher {
|
||||
switch spotPriceSource {
|
||||
case .coinbase:
|
||||
coinbaseSpotPriceFetcher
|
||||
case .coingecko:
|
||||
coinGeckoSpotPriceFetcher
|
||||
}
|
||||
}
|
||||
|
||||
func btcToUsd() async throws -> BigDecimal? {
|
||||
return try await delegate.btcToUsd()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// SpotPriceSource.swift
|
||||
// PriceSource.swift
|
||||
// SatsPrice
|
||||
//
|
||||
// Created by Terry Yiu on 2/20/24.
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SpotPriceSource: CaseIterable, CustomStringConvertible {
|
||||
enum PriceSource: CaseIterable, CustomStringConvertible {
|
||||
case coinbase
|
||||
case coingecko
|
||||
|
||||
Reference in New Issue
Block a user