From 2ee82f8dc9e1e31d77dee9f095f8d059e5593162 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Thu, 12 Dec 2024 23:38:41 -0400 Subject: [PATCH] wip --- ios/Shared/MarketAPI+Electrum.swift | 11 ++++ ios/Widgets/MarketWidget/MarketWidget.swift | 54 ++++++++------- ios/Widgets/Shared/Views/MarketView.swift | 4 +- .../WalletInformationAndMarketWidget.swift | 65 +++++++++++-------- 4 files changed, 80 insertions(+), 54 deletions(-) diff --git a/ios/Shared/MarketAPI+Electrum.swift b/ios/Shared/MarketAPI+Electrum.swift index 6e01912ba..b24f5c8ce 100644 --- a/ios/Shared/MarketAPI+Electrum.swift +++ b/ios/Shared/MarketAPI+Electrum.swift @@ -85,5 +85,16 @@ extension MarketAPI { return marketDataEntry } + + static func fetchMarketData(currency: String, completion: @escaping (Result) -> ()) { + Task { + do { + let marketData = try await fetchMarketData(currency: currency) + completion(.success(marketData)) + } catch { + completion(.failure(error)) + } + } + } } diff --git a/ios/Widgets/MarketWidget/MarketWidget.swift b/ios/Widgets/MarketWidget/MarketWidget.swift index f5efd5b5b..eeaab5d30 100644 --- a/ios/Widgets/MarketWidget/MarketWidget.swift +++ b/ios/Widgets/MarketWidget/MarketWidget.swift @@ -30,42 +30,46 @@ struct MarketWidgetProvider: TimelineProvider { let currentDate = Date() var entries: [MarketWidgetEntry] = [] - var marketDataEntry = MarketWidgetEntry(date: currentDate, marketData: MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)) - entries.append(marketDataEntry) // Initial entry with no data + let marketDataEntry = MarketWidgetEntry(date: currentDate, marketData: MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)) + entries.append(marketDataEntry) // Initial placeholder entry - Task { - let userPreferredCurrency = Currency.getUserPreferredCurrency() - let entry = await fetchMarketDataWithRetry(currency: userPreferredCurrency, retries: 3) + let userPreferredCurrency = Currency.getUserPreferredCurrency() + fetchMarketDataWithRetry(currency: userPreferredCurrency, retries: 3) { marketData in + let entry = MarketWidgetEntry(date: Date(), marketData: marketData) entries.append(entry) - let timeline = Timeline(entries: entries, policy: .atEnd) completion(timeline) } } - private func fetchMarketDataWithRetry(currency: String, retries: Int) async -> MarketWidgetEntry { - var marketData = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0) + private func fetchMarketDataWithRetry(currency: String, retries: Int, completion: @escaping (MarketData) -> ()) { + var attempt = 0 - for attempt in 0.. MarketData { - let marketData = try await MarketAPI.fetchMarketData(currency: currency) - return marketData + attemptFetch() } } diff --git a/ios/Widgets/Shared/Views/MarketView.swift b/ios/Widgets/Shared/Views/MarketView.swift index 2e3ec21ab..892a1c5cd 100644 --- a/ios/Widgets/Shared/Views/MarketView.swift +++ b/ios/Widgets/Shared/Views/MarketView.swift @@ -30,7 +30,7 @@ struct MarketView: View { HStack(alignment: .center, spacing: 0, content: { Text("Sats/\(Currency.getUserPreferredCurrency())").bold().lineLimit(1).font(Font.system(size:11, weight: .medium, design: .default)).foregroundColor(.textColor) Spacer() - Text(marketData.sats == "..." ? "..." : marketData.sats).padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4)).lineLimit(1).minimumScaleFactor(0.1).foregroundColor(.widgetBackground).font(Font.system(size:11, weight: .semibold, design: .default)).background(Color(red: 0.97, green: 0.21, blue: 0.38)).overlay( + Text( marketData.sats).padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4)).lineLimit(1).minimumScaleFactor(0.1).foregroundColor(.widgetBackground).font(Font.system(size:11, weight: .semibold, design: .default)).background(Color(red: 0.97, green: 0.21, blue: 0.38)).overlay( RoundedRectangle(cornerRadius: 4.0) .stroke(Color.containerRed, lineWidth: 4.0)) }) @@ -38,7 +38,7 @@ struct MarketView: View { HStack(alignment: .center, spacing: 0, content: { Text("Price").bold().lineLimit(1).font(Font.system(size:11, weight: . medium, design: .default)).foregroundColor(.textColor) Spacer() - Text(marketData.price == "..." ? "..." : marketData.price).padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4)).lineLimit(1).minimumScaleFactor(0.1).foregroundColor(.widgetBackground).font(Font.system(size:11, weight: .semibold, design: .default)).background(Color(red: 0.29, green: 0.86, blue: 0.73)).overlay( + Text( marketData.price).padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4)).lineLimit(1).minimumScaleFactor(0.1).foregroundColor(.widgetBackground).font(Font.system(size:11, weight: .semibold, design: .default)).background(Color(red: 0.29, green: 0.86, blue: 0.73)).overlay( RoundedRectangle(cornerRadius:4.0) .stroke(Color.containerGreen, lineWidth: 4.0)) }) diff --git a/ios/Widgets/WalletInformationAndMarketWidget/WalletInformationAndMarketWidget.swift b/ios/Widgets/WalletInformationAndMarketWidget/WalletInformationAndMarketWidget.swift index 5436c8458..19142506a 100644 --- a/ios/Widgets/WalletInformationAndMarketWidget/WalletInformationAndMarketWidget.swift +++ b/ios/Widgets/WalletInformationAndMarketWidget/WalletInformationAndMarketWidget.swift @@ -48,43 +48,54 @@ struct WalletInformationAndMarketWidgetProvider: TimelineProvider { let timeline = Timeline(entries: entries, policy: .atEnd) completion(timeline) } else { - Task { - let userPreferredCurrency = Currency.getUserPreferredCurrency() - let allwalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime()) + let userPreferredCurrency = Currency.getUserPreferredCurrency() + let allWalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime()) - var retryCount = 0 - let maxRetries = 3 - var success = false + fetchMarketDataWithRetry(currency: userPreferredCurrency, retries: 3) { marketData in + let entry = WalletInformationAndMarketWidgetEntry(date: Date(), marketData: marketData, allWalletsBalance: allWalletsBalance) + Task { + await entryStore.setLastSuccessfulEntry(entry) + entries.append(entry) + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } + } + } + } - while retryCount < maxRetries && !success { - do { - print("Fetching market data for currency: \(userPreferredCurrency)") - let result = try await MarketAPI.fetchMarketData(currency: userPreferredCurrency) - let entry = WalletInformationAndMarketWidgetEntry(date: Date(), marketData: result, allWalletsBalance: allwalletsBalance) - await entryStore.setLastSuccessfulEntry(entry) - entries.append(entry) - success = true - } catch { - retryCount += 1 - print("Error fetching market data: \(error.localizedDescription). Retry \(retryCount)/\(maxRetries)") - if retryCount == maxRetries { - print("Max retries reached. Blacklisting server.") + private func fetchMarketDataWithRetry(currency: String, retries: Int, completion: @escaping (MarketData) -> ()) { + var attempt = 0 + + func attemptFetch() { + attempt += 1 + print("Attempt \(attempt) to fetch market data.") + + MarketAPI.fetchMarketData(currency: currency) { result in + switch result { + case .success(let marketData): + print("Successfully fetched market data on attempt \(attempt).") + completion(marketData) + case .failure(let error): + print("Error fetching market data: \(error.localizedDescription). Retry \(attempt)/\(retries)") + if attempt < retries { + DispatchQueue.global().asyncAfter(deadline: .now() + 2) { + attemptFetch() + } + } else { + print("Max retries reached.") + Task { if let lastEntry = await entryStore.getLastSuccessfulEntry() { - print("Using last successful entry.") - entries.append(lastEntry) + completion(lastEntry.marketData) } else { - print("Using placeholder entry as fallback.") - entries.append(WalletInformationAndMarketWidgetEntry.placeholder) + completion(WalletInformationAndMarketWidgetEntry.placeholder.marketData) } } } } - - let timeline = Timeline(entries: entries, policy: .atEnd) - print("Submitting timeline with \(entries.count) entries.") - completion(timeline) } } + + attemptFetch() } }