Rename SpotPrice* to Price*

This commit is contained in:
2024-02-21 09:17:54 -05:00
parent 4e1ac7040c
commit e9c44eec2c
8 changed files with 79 additions and 79 deletions

View File

@@ -18,11 +18,11 @@
3AE2D3D52B83E58500DE5F31 /* SatsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */; }; 3AE2D3D52B83E58500DE5F31 /* SatsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */; };
3AE2D3DA2B83FE5F00DE5F31 /* SatsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3D92B83FE5F00DE5F31 /* SatsViewModelTests.swift */; }; 3AE2D3DA2B83FE5F00DE5F31 /* SatsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3D92B83FE5F00DE5F31 /* SatsViewModelTests.swift */; };
3AE2D3DD2B84020200DE5F31 /* BigDecimal in Frameworks */ = {isa = PBXBuildFile; productRef = 3AE2D3DC2B84020200DE5F31 /* BigDecimal */; }; 3AE2D3DD2B84020200DE5F31 /* BigDecimal in Frameworks */ = {isa = PBXBuildFile; productRef = 3AE2D3DC2B84020200DE5F31 /* BigDecimal */; };
3AE2D3DF2B84597100DE5F31 /* SpotPriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3DE2B84597100DE5F31 /* SpotPriceFetcher.swift */; }; 3AE2D3DF2B84597100DE5F31 /* PriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */; };
3AE2D3E12B8459D600DE5F31 /* CoinbaseSpotPriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E02B8459D600DE5F31 /* CoinbaseSpotPriceFetcher.swift */; }; 3AE2D3E12B8459D600DE5F31 /* CoinbasePriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */; };
3AE2D3E32B8461FE00DE5F31 /* CoinGeckoSpotPriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoSpotPriceFetcher.swift */; }; 3AE2D3E32B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */; };
3AE2D3E52B846A8600DE5F31 /* SpotPriceSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E42B846A8600DE5F31 /* SpotPriceSource.swift */; }; 3AE2D3E52B846A8600DE5F31 /* PriceSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */; };
3AE2D3E72B85690200DE5F31 /* SpotPriceFetcherDelegator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E62B85690200DE5F31 /* SpotPriceFetcherDelegator.swift */; }; 3AE2D3E72B85690200DE5F31 /* PriceFetcherDelegator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -57,11 +57,11 @@
3AE2D3BF2B83338E00DE5F31 /* SatsPriceUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsPriceUITestsLaunchTests.swift; sourceTree = "<group>"; }; 3AE2D3BF2B83338E00DE5F31 /* SatsPriceUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsPriceUITestsLaunchTests.swift; sourceTree = "<group>"; };
3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsViewModel.swift; sourceTree = "<group>"; }; 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsViewModel.swift; sourceTree = "<group>"; };
3AE2D3D92B83FE5F00DE5F31 /* SatsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsViewModelTests.swift; sourceTree = "<group>"; }; 3AE2D3D92B83FE5F00DE5F31 /* SatsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsViewModelTests.swift; sourceTree = "<group>"; };
3AE2D3DE2B84597100DE5F31 /* SpotPriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpotPriceFetcher.swift; sourceTree = "<group>"; }; 3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceFetcher.swift; sourceTree = "<group>"; };
3AE2D3E02B8459D600DE5F31 /* CoinbaseSpotPriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinbaseSpotPriceFetcher.swift; sourceTree = "<group>"; }; 3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinbasePriceFetcher.swift; sourceTree = "<group>"; };
3AE2D3E22B8461FE00DE5F31 /* CoinGeckoSpotPriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinGeckoSpotPriceFetcher.swift; sourceTree = "<group>"; }; 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinGeckoPriceFetcher.swift; sourceTree = "<group>"; };
3AE2D3E42B846A8600DE5F31 /* SpotPriceSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpotPriceSource.swift; sourceTree = "<group>"; }; 3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceSource.swift; sourceTree = "<group>"; };
3AE2D3E62B85690200DE5F31 /* SpotPriceFetcherDelegator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpotPriceFetcherDelegator.swift; sourceTree = "<group>"; }; 3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PriceFetcherDelegator.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -115,9 +115,9 @@
children = ( children = (
3AE2D3E82B856B1800DE5F31 /* Network */, 3AE2D3E82B856B1800DE5F31 /* Network */,
3AE2D3A32B83338D00DE5F31 /* ContentView.swift */, 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */,
3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */,
3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */, 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */,
3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */, 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */,
3AE2D3E42B846A8600DE5F31 /* SpotPriceSource.swift */,
3AE2D3A52B83338D00DE5F31 /* Assets.xcassets */, 3AE2D3A52B83338D00DE5F31 /* Assets.xcassets */,
3AE2D3A72B83338D00DE5F31 /* SatsPrice.entitlements */, 3AE2D3A72B83338D00DE5F31 /* SatsPrice.entitlements */,
3AE2D3A02B83338D00DE5F31 /* SatsPrice.xcdatamodeld */, 3AE2D3A02B83338D00DE5F31 /* SatsPrice.xcdatamodeld */,
@@ -155,10 +155,10 @@
3AE2D3E82B856B1800DE5F31 /* Network */ = { 3AE2D3E82B856B1800DE5F31 /* Network */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3AE2D3E02B8459D600DE5F31 /* CoinbaseSpotPriceFetcher.swift */, 3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */,
3AE2D3E22B8461FE00DE5F31 /* CoinGeckoSpotPriceFetcher.swift */, 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */,
3AE2D3DE2B84597100DE5F31 /* SpotPriceFetcher.swift */, 3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */,
3AE2D3E62B85690200DE5F31 /* SpotPriceFetcherDelegator.swift */, 3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */,
); );
path = Network; path = Network;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -299,15 +299,15 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3AE2D3E52B846A8600DE5F31 /* SpotPriceSource.swift in Sources */, 3AE2D3E52B846A8600DE5F31 /* PriceSource.swift in Sources */,
3AE2D3E72B85690200DE5F31 /* SpotPriceFetcherDelegator.swift in Sources */, 3AE2D3E72B85690200DE5F31 /* PriceFetcherDelegator.swift in Sources */,
3AE2D3E12B8459D600DE5F31 /* CoinbaseSpotPriceFetcher.swift in Sources */, 3AE2D3E12B8459D600DE5F31 /* CoinbasePriceFetcher.swift in Sources */,
3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */, 3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */,
3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */, 3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */,
3AE2D3A42B83338D00DE5F31 /* ContentView.swift in Sources */, 3AE2D3A42B83338D00DE5F31 /* ContentView.swift in Sources */,
3AE2D3D52B83E58500DE5F31 /* SatsViewModel.swift in Sources */, 3AE2D3D52B83E58500DE5F31 /* SatsViewModel.swift in Sources */,
3AE2D3E32B8461FE00DE5F31 /* CoinGeckoSpotPriceFetcher.swift in Sources */, 3AE2D3E32B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift in Sources */,
3AE2D3DF2B84597100DE5F31 /* SpotPriceFetcher.swift in Sources */, 3AE2D3DF2B84597100DE5F31 /* PriceFetcher.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -12,11 +12,11 @@ import Combine
struct ContentView: View { struct ContentView: View {
@ObservedObject private var satsViewModel = SatsViewModel() @ObservedObject private var satsViewModel = SatsViewModel()
@State private var spotPriceSource: SpotPriceSource = .coinbase @State private var priceSource: PriceSource = .coinbase
private let dateFormatter = DateFormatter() private let dateFormatter = DateFormatter()
private let spotPriceFetcherDelegator = SpotPriceFetcherDelegator() private let priceFetcherDelegator = PriceFetcherDelegator()
init() { init() {
dateFormatter.dateStyle = .short dateFormatter.dateStyle = .short
@@ -26,7 +26,7 @@ struct ContentView: View {
@MainActor @MainActor
func updatePrice() async { func updatePrice() async {
do { do {
guard let price = try await spotPriceFetcherDelegator.btcToUsd() else { guard let price = try await priceFetcherDelegator.btcToUsd() else {
satsViewModel.btcToUsdString = "" satsViewModel.btcToUsdString = ""
return return
} }
@@ -41,13 +41,13 @@ struct ContentView: View {
var body: some View { var body: some View {
Form { Form {
Section { Section {
Picker("Price Source", selection: $spotPriceSource) { Picker("Price Source", selection: $priceSource) {
ForEach(SpotPriceSource.allCases, id: \.self) { ForEach(PriceSource.allCases, id: \.self) {
Text($0.description) Text($0.description)
} }
} }
.onChange(of: spotPriceSource) { newSpotPriceSource in .onChange(of: priceSource) { newPriceSource in
spotPriceFetcherDelegator.spotPriceSource = newSpotPriceSource priceFetcherDelegator.priceSource = newPriceSource
Task { Task {
await updatePrice() await updatePrice()
} }

View File

@@ -1,5 +1,5 @@
// //
// CoinGeckoSpotPriceFetcher.swift // CoinGeckoPriceFetcher.swift
// SatsPrice // SatsPrice
// //
// Created by Terry Yiu on 2/19/24. // Created by Terry Yiu on 2/19/24.
@@ -8,29 +8,29 @@
import Foundation import Foundation
import BigDecimal import BigDecimal
private struct CoinGeckoSpotPriceResponse: Codable { private struct CoinGeckoPriceResponse: Codable {
let bitcoin: CoinGeckoSpotPrice let bitcoin: CoinGeckoPrice
} }
private struct CoinGeckoSpotPrice: Codable { private struct CoinGeckoPrice: Codable {
let usd: Decimal 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" private static let urlString = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&precision=18"
func btcToUsd() async throws -> BigDecimal? { func btcToUsd() async throws -> BigDecimal? {
do { 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 return nil
} }
let (data, _) = try await URLSession.shared.data(from: url, delegate: nil) let (data, _) = try await URLSession.shared.data(from: url, delegate: nil)
let spotPriceResponse = try JSONDecoder().decode(CoinGeckoSpotPriceResponse.self, from: data) let priceResponse = try JSONDecoder().decode(CoinGeckoPriceResponse.self, from: data)
let spotPrice = spotPriceResponse.bitcoin let price = priceResponse.bitcoin
return BigDecimal(spotPrice.usd) return BigDecimal(price.usd)
} catch { } catch {
return nil return nil
} }

View File

@@ -1,5 +1,5 @@
// //
// CoinbaseSpotPriceFetcher.swift // CoinbasePriceFetcher.swift
// SatsPrice // SatsPrice
// //
// Created by Terry Yiu on 2/19/24. // Created by Terry Yiu on 2/19/24.
@@ -8,37 +8,37 @@
import Foundation import Foundation
import BigDecimal import BigDecimal
private struct CoinbaseSpotPriceResponse: Codable { private struct CoinbasePriceResponse: Codable {
let data: CoinbaseSpotPrice let data: CoinbasePrice
} }
private struct CoinbaseSpotPrice: Codable { private struct CoinbasePrice: Codable {
let amount: String let amount: String
let base: String let base: String
let currency: 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 urlString = "https://api.coinbase.com/v2/prices/BTC-USD/spot"
private static let btc = "BTC" private static let btc = "BTC"
private static let usd = "USD" private static let usd = "USD"
func btcToUsd() async throws -> BigDecimal? { func btcToUsd() async throws -> BigDecimal? {
do { 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 return nil
} }
let (data, _) = try await URLSession.shared.data(from: url, delegate: nil) let (data, _) = try await URLSession.shared.data(from: url, delegate: nil)
let coinbaseSpotPriceResponse = try JSONDecoder().decode(CoinbaseSpotPriceResponse.self, from: data) let coinbasePriceResponse = try JSONDecoder().decode(CoinbasePriceResponse.self, from: data)
let coinbaseSpotPrice = coinbaseSpotPriceResponse.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 nil
} }
return BigDecimal(coinbaseSpotPrice.amount) return BigDecimal(coinbasePrice.amount)
} catch { } catch {
return nil return nil
} }

View File

@@ -1,5 +1,5 @@
// //
// SpotPriceFetcher.swift // PriceFetcher.swift
// SatsPrice // SatsPrice
// //
// Created by Terry Yiu on 2/19/24. // Created by Terry Yiu on 2/19/24.
@@ -8,6 +8,6 @@
import Foundation import Foundation
import BigDecimal import BigDecimal
protocol SpotPriceFetcher { protocol PriceFetcher {
func btcToUsd() async throws -> BigDecimal? func btcToUsd() async throws -> BigDecimal?
} }

View 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()
}
}

View File

@@ -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()
}
}

View File

@@ -1,5 +1,5 @@
// //
// SpotPriceSource.swift // PriceSource.swift
// SatsPrice // SatsPrice
// //
// Created by Terry Yiu on 2/20/24. // Created by Terry Yiu on 2/20/24.
@@ -7,7 +7,7 @@
import Foundation import Foundation
enum SpotPriceSource: CaseIterable, CustomStringConvertible { enum PriceSource: CaseIterable, CustomStringConvertible {
case coinbase case coinbase
case coingecko case coingecko