From 3d3eb220b4f876f36df20ceda1e76101b4c5b73d Mon Sep 17 00:00:00 2001 From: Amir Mohammad Fakhimi Date: Fri, 12 Aug 2022 13:24:59 +0430 Subject: [PATCH] cache data completed (saving money added) --- Shared/ContentView.swift | 6 ++-- Shared/HomeView.swift | 55 +++++++++++++-------------------- Shared/Utils.swift | 51 +++++++++++++++++++++++++++--- Shared/VirtualBuySellView.swift | 10 +++++- Shared/VirtualTradingView.swift | 51 ++++++++++++------------------ 5 files changed, 101 insertions(+), 72 deletions(-) diff --git a/Shared/ContentView.swift b/Shared/ContentView.swift index 970cced..2cc1c11 100644 --- a/Shared/ContentView.swift +++ b/Shared/ContentView.swift @@ -14,10 +14,12 @@ import Reachability struct ContentView: View { let abbreviations = ["BNB", "BTC", "DOGE", "XRP"].sorted() @State var cryptocurrencies: [Cryptocurrency] = [] + @State var unknownErrorAlert: Bool = false + @State var userMoney: Double = 5000 var body: some View { TabView { - HomeView(abbreviations: abbreviations, cryptocurrencies: $cryptocurrencies) + HomeView(abbreviations: abbreviations, cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) .tabItem { Image(systemName: "house") Text("Home") @@ -29,7 +31,7 @@ struct ContentView: View { Text("Exchange Rate") } - VirtualTradingView(cryptocurrencies: $cryptocurrencies, abbreviations: abbreviations) + VirtualTradingView(cryptocurrencies: $cryptocurrencies, abbreviations: abbreviations, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) .tabItem { Image(systemName: "chart.line.uptrend.xyaxis") Text("Virtual Trading") diff --git a/Shared/HomeView.swift b/Shared/HomeView.swift index 15d7d2b..46e8675 100644 --- a/Shared/HomeView.swift +++ b/Shared/HomeView.swift @@ -14,8 +14,9 @@ struct HomeView: View { let abbreviations: [String] @Binding var cryptocurrencies: [Cryptocurrency] + @Binding var userMoney: Double + @Binding var unknownErrorAlert: Bool - @State var unknownErrorAlert: Bool = false @State var isSyncing: Bool = false @State var favoriteCryptocurrencies: [Cryptocurrency] = [] @@ -149,7 +150,7 @@ struct HomeView: View { let button = getStarButton(cryptocurrency: cryptocurrency, imageName: "star.fill") { removeFromFavoriteCryptocarrencies(cryptocurrency) cryptocurrency.isFavorite = false - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } return BarChartView(data: ChartData(values: data), title: cryptocurrency.name, legend: "Daily", form: ChartForm.medium, cornerButton: button, valueSpecifier: "%.2f") @@ -222,14 +223,14 @@ struct HomeView: View { getStarButton(cryptocurrency: cryptocurrency, imageName: "star.fill") { cryptocurrency.isFavorite = false removeFromFavoriteCryptocarrencies(cryptocurrency) - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } } else { getStarButton(cryptocurrency: cryptocurrency, imageName: "star") { cryptocurrency.isFavorite = true favoriteCryptocurrencies.append(cryptocurrency) favoriteCryptocurrencies = sortCryptocurrencyByName(favoriteCryptocurrencies) - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } } } @@ -242,16 +243,6 @@ struct HomeView: View { .coordinateSpace(name: "") } - func doDummyOnCryptocurrencies() { - let dummy = Cryptocurrency(symbol: "", name: "", history: [], abbreviation: "") - cryptocurrencies.append(dummy) - cryptocurrencies.removeLast() - - for cryptocurrency in cryptocurrencies { - writeData(cryptocurrency) - } - } - func getData() { isSyncing = true @@ -282,9 +273,7 @@ struct HomeView: View { // directory available try FileManager.default.createDirectory(at: directoryName, withIntermediateDirectories: true) - for abbreviation in abbreviations { - readData(abbreviation) - } + readAllData() } catch { // directory unavailable do { @@ -297,11 +286,6 @@ struct HomeView: View { } } - func getProjectDirectory() -> URL { - let projectDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] - return projectDirectory.appendingPathComponent("cryptocurrencies", isDirectory: true) - } - func getCryptocurrencyData(_ abbreviation: String, _ apiKey: String) { let request = NSMutableURLRequest(url: NSURL(string: "https://api.twelvedata.com/time_series?apikey=\(apiKey)&interval=1day&symbol=\(abbreviation)/USD&dp=2&format=JSON")! as URL, cachePolicy: .useProtocolCachePolicy, @@ -347,32 +331,34 @@ struct HomeView: View { let cryptocurrency = Cryptocurrency(symbol: meta["symbol"]!, name: meta["currency_base"]!, history: history, abbreviation: abbreviation) cryptocurrencies.append(cryptocurrency) cryptocurrencies = sortCryptocurrencyByName(cryptocurrencies) - writeData(cryptocurrency) + writeData(cryptocurrency: cryptocurrency, unknownErrorAlert: $unknownErrorAlert) } else { cryptocurrency!.history = history - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } } else { runOutOfAPICredits = true + readAllData() } } else { unknownErrorAlert = true } } - func writeData(_ cryptocurrency: Cryptocurrency) { + func readAllData() { + let directoryName = getProjectDirectory() + do { - let directoryName = getProjectDirectory() - - let jsonEncoder = JSONEncoder() - let jsonData = try jsonEncoder.encode(cryptocurrency) - let json = String(data: jsonData, encoding: .utf8) - let cryptocurrencyDir = directoryName.appendingPathComponent("\(cryptocurrency.abbreviation).txt", isDirectory: true) - try json?.write(to: cryptocurrencyDir, atomically: true, encoding: String.Encoding.utf16) + let moneyDir = directoryName.appendingPathComponent("money.txt", isDirectory: true) + userMoney = Double(try String(contentsOf: moneyDir, encoding: .utf16))! } catch { unknownErrorAlert = true } + + for abbreviation in abbreviations { + readData(abbreviation) + } } func readData(_ cryptocurrencyAbbreviation: String) { @@ -392,7 +378,7 @@ struct HomeView: View { } else { getCryptocurrency!.history = cryptocurrency.history getCryptocurrency!.price = cryptocurrency.price - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } } catch { unknownErrorAlert = true @@ -418,7 +404,7 @@ struct HomeView: View { } else { do { try updatePrice(abbreviation, data!) - doDummyOnCryptocurrencies() + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } catch { unknownErrorAlert = true } @@ -440,6 +426,7 @@ struct HomeView: View { } } else { runOutOfAPICredits = true + readAllData() } } else { diff --git a/Shared/Utils.swift b/Shared/Utils.swift index 030f9e4..14662ef 100644 --- a/Shared/Utils.swift +++ b/Shared/Utils.swift @@ -15,21 +15,21 @@ func getStarButton(cryptocurrency: Cryptocurrency, imageName: String, action: @e Button(action: action) { AnyView(Image(systemName: imageName) .foregroundColor(Color.yellow) - .font(.system(size: 20, weight: .bold))) + .font(.system(size: 20, weight: .bold))) } } func formatDouble(value: Double) -> String { var formattedValue = String(format: "%.5f", value) - + while formattedValue.last == "0" { formattedValue.removeLast() } - + if formattedValue.last == "." { formattedValue.removeLast() } - + return formattedValue } @@ -59,3 +59,46 @@ func getDefaultRectangle() -> some View { .cornerRadius(20) .shadow(color: Color.gray, radius: 6) } + +func getProjectDirectory() -> URL { + let projectDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] + return projectDirectory.appendingPathComponent("cryptocurrencies", isDirectory: true) +} + +func doDummyOnCryptocurrencies(cryptocurrencies: Binding<[Cryptocurrency]>, userMoney: Binding, unknownErrorAlert: Binding) { + let dummy = Cryptocurrency(symbol: "", name: "", history: [], abbreviation: "") + cryptocurrencies.wrappedValue.append(dummy) + cryptocurrencies.wrappedValue.removeLast() + + writeAllData(cryptocurrencies: cryptocurrencies, userMoney: userMoney, unknownErrorAlert: unknownErrorAlert) +} + +func writeAllData(cryptocurrencies: Binding<[Cryptocurrency]>, userMoney: Binding, unknownErrorAlert: Binding) { + let directoryName = getProjectDirectory() + + do { + let moneyDir = directoryName.appendingPathComponent("money.txt", isDirectory: true) + try String(userMoney.wrappedValue).write(to: moneyDir, atomically: true, encoding: String.Encoding.utf16) + } catch { + unknownErrorAlert.wrappedValue = true + } + + + for cryptocurrency in cryptocurrencies.wrappedValue { + writeData(cryptocurrency: cryptocurrency, unknownErrorAlert: unknownErrorAlert) + } +} + +func writeData(cryptocurrency: Cryptocurrency, unknownErrorAlert: Binding) { + do { + let directoryName = getProjectDirectory() + + let jsonEncoder = JSONEncoder() + let jsonData = try jsonEncoder.encode(cryptocurrency) + let json = String(data: jsonData, encoding: .utf8) + let cryptocurrencyDir = directoryName.appendingPathComponent("\(cryptocurrency.abbreviation).txt", isDirectory: true) + try json?.write(to: cryptocurrencyDir, atomically: true, encoding: String.Encoding.utf16) + } catch { + unknownErrorAlert.wrappedValue = true + } +} diff --git a/Shared/VirtualBuySellView.swift b/Shared/VirtualBuySellView.swift index dbf0b45..8b66405 100644 --- a/Shared/VirtualBuySellView.swift +++ b/Shared/VirtualBuySellView.swift @@ -10,6 +10,8 @@ import SwiftUI struct VirtualBuySellView: View { @State var cryptocurrency: Cryptocurrency @Binding var userMoney: Double + @Binding var cryptocurrencies: [Cryptocurrency] + @Binding var unknownErrorAlert: Bool @State private var enoughMoneyAlert = false @State private var enoughCoinAlert = false @@ -19,9 +21,11 @@ struct VirtualBuySellView: View { @State private var dataDidNotLoadAlert = false @State private var amount = "" - init(_ cryptocurrency: Cryptocurrency, _ userMoney: Binding) { + init(_ cryptocurrency: Cryptocurrency, _ userMoney: Binding, cryptocurrencies: Binding<[Cryptocurrency]>, unknownErrorAlert: Binding) { self.cryptocurrency = cryptocurrency self._userMoney = userMoney + self._cryptocurrencies = cryptocurrencies + self._unknownErrorAlert = unknownErrorAlert } func format_double(value: Double) -> String { @@ -72,6 +76,8 @@ struct VirtualBuySellView: View { userMoney -= cost cryptocurrency.virtualTradingAmount += Double(amount)! buySuccessAlert = true + + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } amount = "" @@ -110,6 +116,8 @@ struct VirtualBuySellView: View { userMoney += cost cryptocurrency.virtualTradingAmount -= Double(amount)! sellSuccessAlert = true + + doDummyOnCryptocurrencies(cryptocurrencies: $cryptocurrencies, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } amount = "" diff --git a/Shared/VirtualTradingView.swift b/Shared/VirtualTradingView.swift index 5d4cfb2..cc18991 100644 --- a/Shared/VirtualTradingView.swift +++ b/Shared/VirtualTradingView.swift @@ -9,16 +9,19 @@ import SwiftUI struct VirtualTradingView: View { - @State var userMoney: Double = 5000 + @Binding var userMoney: Double @Binding var cryptocurrencies: [Cryptocurrency] + @Binding var unknownErrorAlert: Bool let abbreviations: [String] @State var dataDidNotLoadAlert: Bool = false - init(cryptocurrencies: Binding<[Cryptocurrency]>, abbreviations: [String]) { + init(cryptocurrencies: Binding<[Cryptocurrency]>, abbreviations: [String], userMoney: Binding, unknownErrorAlert: Binding) { self._cryptocurrencies = cryptocurrencies self.abbreviations = abbreviations + self._userMoney = userMoney + self._unknownErrorAlert = unknownErrorAlert } func showCoinBar(cryptocurrency: Cryptocurrency) -> some View { @@ -27,7 +30,7 @@ struct VirtualTradingView: View { .padding([.leading, .bottom, .trailing]) .overlay( NavigationLink { - VirtualBuySellView(cryptocurrency, $userMoney) + VirtualBuySellView(cryptocurrency, $userMoney, cryptocurrencies: $cryptocurrencies, unknownErrorAlert: $unknownErrorAlert) } label: { HStack { getLeftSideOfRectangle(cryptocurrency: cryptocurrency, vSpacing: vSpacing) @@ -53,27 +56,6 @@ struct VirtualTradingView: View { } ) -// return HStack { -// Image(cryptocurrency.name) -// .resizable() -// .scaledToFit() -// .frame(width: 70, height: 70) -// .padding(.trailing) -// VStack { -// NavigationLink { -// VirtualBuySellView(cryptocurrency, $userMoney) -// } label: { -// VStack(alignment: .leading) { -// Text(cryptocurrency.completeName) -// .bold() -// Text("Current Amount: \(formatDouble(value: cryptocurrency.amount))") -// Text("Current Price: \("$" + formatDouble(value: cryptocurrency.price))") -// } -// } -// } -// } -// .padding(.top, 5) -// .padding(.bottom, 5) } var body: some View { @@ -90,16 +72,20 @@ struct VirtualTradingView: View { Divider() .background(.black) - HStack{ + HStack { Image("Dollar") .resizable() .scaledToFit() .frame(width: 50, height: 50) - Text("Current Money: \("$" + formatDouble(value: userMoney))") - .bold() - .italic() - .foregroundColor(.black) - .font(.system(size: 20, weight: .light, design: .default)) + Button { + + } label: { + Text("Current Money: \("$" + formatDouble(value: userMoney))") + .bold() + .italic() + .foregroundColor(.black) + .font(.system(size: 20, weight: .light, design: .default)) + } } .padding(.top, 5) .padding(.bottom, 5) @@ -125,8 +111,11 @@ struct VirtualTraidingView_Previews: PreviewProvider { Cryptocurrency(symbol: "BTC/USD", name: "Bitcoin", history: [], abbreviation: "BTC") ] static let abbreviations = ["BNB", "BTC"] + + @State static var userMoney: Double = 5000 + @State static var unknownErrorAlert: Bool = false static var previews: some View { - VirtualTradingView(cryptocurrencies: $cryptocurrencies, abbreviations: abbreviations) + VirtualTradingView(cryptocurrencies: $cryptocurrencies, abbreviations: abbreviations, userMoney: $userMoney, unknownErrorAlert: $unknownErrorAlert) } }