From 129dbd170a63dcf7a707c0e313c960674d41daa5 Mon Sep 17 00:00:00 2001 From: Manu R Date: Mon, 9 Dec 2024 11:09:30 +0530 Subject: [PATCH 1/3] Fix Widget Refresh Bug --- OBAKitCore/Orchestration/CoreApplication.swift | 9 +++++++++ OBAWidget/Main/OBAAppIntents.swift | 10 +++++----- OBAWidget/Provider/WidgetDataProvider.swift | 12 +++++++----- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/OBAKitCore/Orchestration/CoreApplication.swift b/OBAKitCore/Orchestration/CoreApplication.swift index 44d4dd50..b8071af1 100644 --- a/OBAKitCore/Orchestration/CoreApplication.swift +++ b/OBAKitCore/Orchestration/CoreApplication.swift @@ -129,6 +129,15 @@ open class CoreApplication: NSObject, self.apiService = RESTAPIService(APIServiceConfiguration(baseURL: region.OBABaseURL, apiKey: config.apiKey, uuid: userUUID, appVersion: config.appVersion, regionIdentifier: region.regionIdentifier)) } + public func getNewRefreshedRESTAPIService() -> RESTAPIService? { + guard let region = regionsService.currentRegion else { + return nil + } + let apiService = RESTAPIService(APIServiceConfiguration(baseURL: region.OBABaseURL, apiKey: config.apiKey, uuid: userUUID, appVersion: config.appVersion, regionIdentifier: region.regionIdentifier)) + + return apiService + } + // MARK: - Obaco public private(set) var obacoService: ObacoAPIService? { diff --git a/OBAWidget/Main/OBAAppIntents.swift b/OBAWidget/Main/OBAAppIntents.swift index 6a991c33..120e5b14 100644 --- a/OBAWidget/Main/OBAAppIntents.swift +++ b/OBAWidget/Main/OBAAppIntents.swift @@ -11,9 +11,9 @@ import OBAKitCore struct ConfigurationAppIntent: AppIntent, WidgetConfigurationIntent { static var title: LocalizedStringResource = "Bookmarks" - static var description: IntentDescription = IntentDescription("") - - - -} + static var description: IntentDescription = IntentDescription("Get the transit info") + func perform() async throws -> some IntentResult { + return .result() + } +} diff --git a/OBAWidget/Provider/WidgetDataProvider.swift b/OBAWidget/Provider/WidgetDataProvider.swift index 3c5c8d22..486a531b 100644 --- a/OBAWidget/Provider/WidgetDataProvider.swift +++ b/OBAWidget/Provider/WidgetDataProvider.swift @@ -42,11 +42,13 @@ class WidgetDataProvider: NSObject, ObservableObject { /// Loads arrivals and departures for all favorited bookmarks for the widget. public func loadData() async { - guard let apiService = app.apiService else { return } - + arrDepDic = [:] + guard let apiService = app.getNewRefreshedRESTAPIService() else { + return + } + let bookmarks = getBookmarks() - .filter { $0.isTripBookmark && $0.regionIdentifier == app.regionsService.currentRegion?.id } - + for bookmark in bookmarks { await fetchArrivalData(for: bookmark, apiService: apiService) } @@ -82,7 +84,7 @@ class WidgetDataProvider: NSObject, ObservableObject { /// Retrieves the best available bookmarks. public func getBookmarks() -> [Bookmark] { - return bestAvailableBookmarks + return bestAvailableBookmarks.filter { $0.isTripBookmark && $0.regionIdentifier == app.regionsService.currentRegion?.id } } /// Dictionary to store arrival and departure data grouped by trip keys. From bce9527298f507cea2f97d9c8ff102d3343a05a7 Mon Sep 17 00:00:00 2001 From: Manu R Date: Mon, 9 Dec 2024 21:54:05 +0530 Subject: [PATCH 2/3] Improve WidgetDataProivder --- OBAWidget/Provider/WidgetDataProvider.swift | 80 ++++++++++++--------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/OBAWidget/Provider/WidgetDataProvider.swift b/OBAWidget/Provider/WidgetDataProvider.swift index 486a531b..f5850b25 100644 --- a/OBAWidget/Provider/WidgetDataProvider.swift +++ b/OBAWidget/Provider/WidgetDataProvider.swift @@ -10,28 +10,24 @@ import CoreLocation /// `WidgetDataProvider` is responsible for fetching and providing relevant data to the widget timeline provider. class WidgetDataProvider: NSObject, ObservableObject { - - public let formatters = Formatters( - locale: Locale.autoupdatingCurrent, - calendar: Calendar.autoupdatingCurrent, - themeColors: ThemeColors.shared - ) - static let shared = WidgetDataProvider() + private let userDefaults = UserDefaults(suiteName: Bundle.main.appGroup!)! - private lazy var locationManager = CLLocationManager() private lazy var locationService = LocationService( userDefaults: userDefaults, locationManager: locationManager ) - + private lazy var app: CoreApplication = { - let bundledRegions = Bundle.main.path(forResource: "regions", ofType: "json")! - let config = CoreAppConfig(appBundle: Bundle.main, userDefaults: userDefaults, bundledRegionsFilePath: bundledRegions) + let config = CoreAppConfig( + appBundle: Bundle.main, + userDefaults: userDefaults, + bundledRegionsFilePath: Bundle.main.path(forResource: "regions", ofType: "json")! + ) return CoreApplication(config: config) }() - + private var bestAvailableBookmarks: [Bookmark] { var bookmarks = app.userDataStore.favoritedBookmarks if bookmarks.isEmpty { @@ -39,21 +35,41 @@ class WidgetDataProvider: NSObject, ObservableObject { } return bookmarks } - + + /// Dictionary mapping trip bookmark keys to arrival/departure data. + private var arrDepDic = [TripBookmarkKey: [ArrivalDeparture]]() + + /// Formatters for localization and styling. + let formatters = Formatters( + locale: Locale.autoupdatingCurrent, + calendar: Calendar.autoupdatingCurrent, + themeColors: ThemeColors.shared + ) + /// Loads arrivals and departures for all favorited bookmarks for the widget. - public func loadData() async { - arrDepDic = [:] + func loadData() async { + arrDepDic = [:] + guard let apiService = app.getNewRefreshedRESTAPIService() else { + Logger.error("Failed to get REST API Service.") return } let bookmarks = getBookmarks() + guard !bookmarks.isEmpty else { + Logger.info("No bookmarks found to load data.") + return + } - for bookmark in bookmarks { - await fetchArrivalData(for: bookmark, apiService: apiService) + await withTaskGroup(of: Void.self) { group in + bookmarks.forEach { bookmark in + group.addTask { [weak self] in + await self?.fetchArrivalData(for: bookmark, apiService: apiService) + } + } } } - + /// Fetch arrival data for a specific bookmark and update the dictionary. private func fetchArrivalData(for bookmark: Bookmark, apiService: RESTAPIService) async { do { @@ -62,31 +78,27 @@ class WidgetDataProvider: NSObject, ObservableObject { minutesBefore: 0, minutesAfter: 60 ).entry - + await MainActor.run { - let keysAndDeps = stopArrivals.arrivalsAndDepartures.tripKeyGroupedElements - for (key, deps) in keysAndDeps { - self.arrDepDic[key] = deps + stopArrivals.arrivalsAndDepartures.tripKeyGroupedElements.forEach { key, deps in + arrDepDic[key] = deps } } } catch { - Logger - .error( - "Error fetching data for bookmark \(bookmark.name) with bookmark id: \(bookmark.id): \(error)" - ) + Logger.error(""" + Error fetching data for bookmark: '\(bookmark.name)' + (ID: \(bookmark.id)). Error: \(error.localizedDescription) + """) } } - + /// Looks up arrival and departure data for a given trip key. - public func lookupArrivalDeparture(with key: TripBookmarkKey) -> [ArrivalDeparture] { - return arrDepDic[key, default: []] + func lookupArrivalDeparture(with key: TripBookmarkKey) -> [ArrivalDeparture] { + arrDepDic[key, default: []] } - - /// Retrieves the best available bookmarks. + + /// Gets bookmarks of the selected region. public func getBookmarks() -> [Bookmark] { return bestAvailableBookmarks.filter { $0.isTripBookmark && $0.regionIdentifier == app.regionsService.currentRegion?.id } } - - /// Dictionary to store arrival and departure data grouped by trip keys. - private var arrDepDic = [TripBookmarkKey: [ArrivalDeparture]]() } From 9e4e4c3cbc7e7b3bd4c8ec36bf0603e6ed8a561f Mon Sep 17 00:00:00 2001 From: Manu R Date: Tue, 10 Dec 2024 08:38:31 +0530 Subject: [PATCH 3/3] Apply minor fixes --- OBAKitCore/Orchestration/CoreApplication.swift | 11 +---------- OBAWidget/Provider/WidgetDataProvider.swift | 6 ++++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/OBAKitCore/Orchestration/CoreApplication.swift b/OBAKitCore/Orchestration/CoreApplication.swift index b8071af1..289f4a94 100644 --- a/OBAKitCore/Orchestration/CoreApplication.swift +++ b/OBAKitCore/Orchestration/CoreApplication.swift @@ -91,7 +91,7 @@ open class CoreApplication: NSObject, } /// This function reloads the REST API and Obaco Services. - private func refreshServices() { + public func refreshServices() { refreshRESTAPIService() refreshObacoService() apiServicesRefreshed() @@ -129,15 +129,6 @@ open class CoreApplication: NSObject, self.apiService = RESTAPIService(APIServiceConfiguration(baseURL: region.OBABaseURL, apiKey: config.apiKey, uuid: userUUID, appVersion: config.appVersion, regionIdentifier: region.regionIdentifier)) } - public func getNewRefreshedRESTAPIService() -> RESTAPIService? { - guard let region = regionsService.currentRegion else { - return nil - } - let apiService = RESTAPIService(APIServiceConfiguration(baseURL: region.OBABaseURL, apiKey: config.apiKey, uuid: userUUID, appVersion: config.appVersion, regionIdentifier: region.regionIdentifier)) - - return apiService - } - // MARK: - Obaco public private(set) var obacoService: ObacoAPIService? { diff --git a/OBAWidget/Provider/WidgetDataProvider.swift b/OBAWidget/Provider/WidgetDataProvider.swift index f5850b25..1a38820b 100644 --- a/OBAWidget/Provider/WidgetDataProvider.swift +++ b/OBAWidget/Provider/WidgetDataProvider.swift @@ -48,9 +48,11 @@ class WidgetDataProvider: NSObject, ObservableObject { /// Loads arrivals and departures for all favorited bookmarks for the widget. func loadData() async { - arrDepDic = [:] - guard let apiService = app.getNewRefreshedRESTAPIService() else { + arrDepDic = [:] + app.refreshServices() + + guard let apiService = app.apiService else { Logger.error("Failed to get REST API Service.") return }