Skip to content

Commit

Permalink
feat(app): group by metro endpoint query
Browse files Browse the repository at this point in the history
  • Loading branch information
krystxf committed Jun 21, 2024
1 parent 6b45cad commit 08a089f
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 120 deletions.
49 changes: 34 additions & 15 deletions app/Common/Utils/networkUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,69 @@ enum FetchError:
case InvalidaData
}

typealias DeparturesByGtfsIDs = [String: [ApiDeparture]]
typealias GroupedDepartures = [String: [ApiDeparture]]

func getStationDepartures(station: String) async throws -> [ApiDeparture] {
let endpoint = "\(METRO_NOW_API)/metro?station=\(station)&ungrouped=true"
enum GroupBy: String {
case platform
case heading
}

func getDepartures(stations: [String] = [], gtfsIDs: [String] = [], groupBy: GroupBy) async throws -> GroupedDepartures {
if stations.count == 0, gtfsIDs.count == 0 {
print("No station & No GtfsID")
return [:]
}

let platformParam = (gtfsIDs.map { "platform=\($0)" }).joined(separator: "&")
let stationParam = (stations.map { "station=\($0)" }).joined(separator: "&")
let endpoint = "\(METRO_NOW_API)/metro?\(platformParam)&\(stationParam)&groupBy=\(groupBy.rawValue)"
print(endpoint)
guard let url = URL(string: endpoint) else { throw FetchError.InvalidURL }
let (data, response) = try await URLSession.shared.data(from: url)

guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
print("Response not 200")
return []
return [:]
}

do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode([ApiDeparture].self, from: data)

return try decoder.decode(GroupedDepartures.self, from: data)

} catch {
throw FetchError.InvalidaData
}
}

func getDeparturesByGtfsID(gtfsIDs: [String]) async throws -> DeparturesByGtfsIDs {
let params = (gtfsIDs.map { "platform=\($0)" }).joined(separator: "&")
let endpoint = "\(METRO_NOW_API)/metro?\(params)"
func getDepartures(stations: [String] = [], gtfsIDs: [String] = []) async throws -> [ApiDeparture] {
if stations.count == 0, gtfsIDs.count == 0 {
print("No station & No GtfsID")
return []
}
let platformParam = (gtfsIDs.map { "platform=\($0)" }).joined(separator: "&")
let stationParam = (stations.map { "station=\($0)" }).joined(separator: "&")
let endpoint = "\(METRO_NOW_API)/metro?\(platformParam)&\(stationParam)"
print(endpoint)
guard let url = URL(string: endpoint) else { throw FetchError.InvalidURL }

let (data, response) = try await URLSession.shared.data(from: url)

guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
print("Response not 200")
return [:]
return []
}

do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode(DeparturesByGtfsIDs.self, from: data)

return try decoder.decode([ApiDeparture].self, from: data)

} catch {
throw FetchError.InvalidaData
}
}

func getDeparturesByGtfsID(_ gtfsID: String) async throws -> [ApiDeparture]? {
let res = try await (getDeparturesByGtfsID(gtfsIDs: [gtfsID]))
return res[gtfsID]
}
4 changes: 2 additions & 2 deletions app/metro-now-widgets/Core/Provider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct Provider: TimelineProvider {

Task {
let gtfsIDs = closestStation.properties.platforms.map(\.gtfsId)
let departures = try! await getDeparturesByGtfsID(gtfsIDs: gtfsIDs)
let departures = await (try! getDepartures(gtfsIDs: gtfsIDs, groupBy: .platform))

var parsedDepartures: [WidgetEntryDeparture] = []

Expand Down Expand Up @@ -66,7 +66,7 @@ struct Provider: TimelineProvider {

Task {
let gtfsIDs = closestStation.properties.platforms.map(\.gtfsId)
let departures = try! await getDeparturesByGtfsID(gtfsIDs: gtfsIDs)
let departures = await (try! getDepartures(gtfsIDs: gtfsIDs, groupBy: .platform))

var entries: [WidgetEntry] = []
var parsedDepartures: [WidgetEntryDeparture] = []
Expand Down
24 changes: 13 additions & 11 deletions app/metro-now/Core/Map/StationLocationMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct StationLocationMapView: View {
let mapUrl: URL
@StateObject private var locationModel = LocationModel()
@State var distance: Double = -1
@State private var departures: [ApiDeparture] = []
@State private var departures: GroupedDepartures = [:]
@State private var errorMessage: String?
@State private var cameraPosition: MapCameraPosition

Expand Down Expand Up @@ -101,14 +101,16 @@ struct StationLocationMapView: View {
Spacer()
}

ForEach(departures, id: \.departure) { departure in
let departureDates = [departure.departure]
ForEach(Array(departures.keys), id: \.self) { k in
let d = departures[k]!

PlatformListItemView(
direction: departure.heading,
departureDates: departureDates,
metroLine: departure.line
)
if d.count > 0 {
PlatformListItemView(
direction: d[0].heading,
departureDates: d.map(\.departure),
metroLine: d[0].line
)
}
}
}
}
Expand All @@ -119,7 +121,6 @@ struct StationLocationMapView: View {
.toolbarBackground(.thinMaterial, for: .navigationBar)
.toolbarBackground(.automatic, for: .navigationBar)
.onReceive(locationModel.$location) { location in

guard let location else {
print("Unknown location")
return
Expand All @@ -137,15 +138,16 @@ struct StationLocationMapView: View {
distance = userLocation.distance(from: stationLocation)
}.refreshable {
do {
departures = try await getStationDepartures(station: stationName)
departures = try await getDepartures(stations: [stationName], groupBy: .heading)
} catch {
errorMessage = "Failed to fetch departures: \(error)"
}
}
.onAppear {
Task {
do {
departures = try await getStationDepartures(station: stationName)
departures = try await (getDepartures(stations: [stationName], groupBy: .heading))

} catch {
errorMessage = "Failed to fetch departures: \(error)"
}
Expand Down
4 changes: 2 additions & 2 deletions app/metro-now/Core/PlatformDetail/PlatformDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ struct PlatformDetailView: View {
.padding(.top, 50)
.task {
do {
departures = try await getDeparturesByGtfsID(gtfsID)
departures = try await (getDepartures(gtfsIDs: [gtfsID], groupBy: .platform))[gtfsID]

} catch {
print(error)
}
}
.refreshable {
do {
departures = try await getDeparturesByGtfsID(gtfsID)
departures = try await (getDepartures(gtfsIDs: [gtfsID], groupBy: .platform))[gtfsID]

} catch {
print(error)
Expand Down
Loading

0 comments on commit 08a089f

Please sign in to comment.