Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Widget Kit Refreshing Bug #778

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion OBAKitCore/Orchestration/CoreApplication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 5 additions & 5 deletions OBAWidget/Main/OBAAppIntents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
92 changes: 54 additions & 38 deletions OBAWidget/Provider/WidgetDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,68 @@ 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 {
bookmarks = app.userDataStore.bookmarks
}
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 {
guard let apiService = app.apiService else { return }

func loadData() async {

arrDepDic = [:]
app.refreshServices()

guard let apiService = app.apiService else {
Logger.error("Failed to get REST API Service.")
return
}

let bookmarks = getBookmarks()
.filter { $0.isTripBookmark && $0.regionIdentifier == app.regionsService.currentRegion?.id }

for bookmark in bookmarks {
await fetchArrivalData(for: bookmark, apiService: apiService)
guard !bookmarks.isEmpty else {
Logger.info("No bookmarks found to load data.")
return
}

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 {
Expand All @@ -60,31 +80,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
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]]()
}
Loading