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

feat(analytics): log mode and no_trips in tapped_departure #650

Merged
merged 2 commits into from
Jan 14, 2025
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
4 changes: 4 additions & 0 deletions iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
8CA1FB772BF813F500384658 /* TripDetailsStopListSplitViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA1FB762BF813F500384658 /* TripDetailsStopListSplitViewTests.swift */; };
8CA485B82BDC679A00E84E1F /* VehicleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA485B72BDC679A00E84E1F /* VehicleExtension.swift */; };
8CA606A92CC02FBC0019C448 /* ViewInspectorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA606A82CC02FBC0019C448 /* ViewInspectorExtensions.swift */; };
8CA7CDA02D359357008EE7D2 /* DestinationRowAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CA7CD9F2D359353008EE7D2 /* DestinationRowAnalytics.swift */; };
8CB28DB92C2CC5AD0036258E /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB28DB82C2CC5AD0036258E /* MapViewModel.swift */; };
8CB823D62BC5E85C002C87E0 /* SheetNavigationStackEntryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB823D52BC5E85C002C87E0 /* SheetNavigationStackEntryTests.swift */; };
8CB823D92BC5EDD2002C87E0 /* StopDetailsRouteViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CB823D82BC5EDD2002C87E0 /* StopDetailsRouteViewTests.swift */; };
Expand Down Expand Up @@ -396,6 +397,7 @@
8CA1FB762BF813F500384658 /* TripDetailsStopListSplitViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TripDetailsStopListSplitViewTests.swift; sourceTree = "<group>"; };
8CA485B72BDC679A00E84E1F /* VehicleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleExtension.swift; sourceTree = "<group>"; };
8CA606A82CC02FBC0019C448 /* ViewInspectorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewInspectorExtensions.swift; sourceTree = "<group>"; };
8CA7CD9F2D359353008EE7D2 /* DestinationRowAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationRowAnalytics.swift; sourceTree = "<group>"; };
8CB28DB82C2CC5AD0036258E /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = "<group>"; };
8CB823D52BC5E85C002C87E0 /* SheetNavigationStackEntryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetNavigationStackEntryTests.swift; sourceTree = "<group>"; };
8CB823D82BC5EDD2002C87E0 /* StopDetailsRouteViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StopDetailsRouteViewTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1162,6 +1164,7 @@
children = (
9A52B3392C6E7C7D0028EEAB /* AlertDetailsAnalytics.swift */,
ED24EADD2C1A986900A7BE4D /* AnalyticsProvider.swift */,
8CA7CD9F2D359353008EE7D2 /* DestinationRowAnalytics.swift */,
ED24EAD72C1A941E00A7BE4D /* NearbyTransitAnalytics.swift */,
EDE92FA52C3DD675007AD2F6 /* ScreenTracker.swift */,
ED24EADB2C1A95A900A7BE4D /* StopDetailsAnalytics.swift */,
Expand Down Expand Up @@ -1642,6 +1645,7 @@
6E35D4D02B72C7B700A2BF95 /* HomeMapView.swift in Sources */,
9ACE4FD02CE6707900FEB006 /* StopDetailsPage.swift in Sources */,
9A4DB77F2CA4A32800E8755B /* SearchOverlay.swift in Sources */,
8CA7CDA02D359357008EE7D2 /* DestinationRowAnalytics.swift in Sources */,
8CC1BB402B59D1F6005386FE /* LocationDataManager.swift in Sources */,
9A6ACA2B2CD0096A00299AF5 /* MoreSectionView.swift in Sources */,
6E3C8D7E2C11FDA80059C28C /* ActionButton.swift in Sources */,
Expand Down
57 changes: 57 additions & 0 deletions iosApp/iosApp/Analytics/DestinationRowAnalytics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// DestinationRowAnalytics.swift
// iosApp
//
// Created by Horn, Melody on 2025-01-13.
// Copyright © 2025 MBTA. All rights reserved.
//

import FirebaseAnalytics
import shared

protocol DestinationRowAnalytics {
func tappedDeparture(

Check notice on line 13 in iosApp/iosApp/Analytics/DestinationRowAnalytics.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Analytics/DestinationRowAnalytics.swift#L13

Function Parameter Count Violation: Function should have 5 parameters or less: it currently has 6 (function_parameter_count)
routeId: String,
stopId: String,
pinned: Bool,
alert: Bool,
routeType: RouteType,
noTrips: RealtimePatterns.NoTripsFormat?
)
}

extension AnalyticsProvider: DestinationRowAnalytics {
func tappedDeparture(

Check notice on line 24 in iosApp/iosApp/Analytics/DestinationRowAnalytics.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Analytics/DestinationRowAnalytics.swift#L24

Function Parameter Count Violation: Function should have 5 parameters or less: it currently has 6 (function_parameter_count)
routeId: String,
stopId: String,
pinned: Bool,
alert: Bool,
routeType: RouteType,
noTrips: RealtimePatterns.NoTripsFormat?
) {
let mode = switch routeType {
case .bus: "bus"
case .commuterRail: "commuter rail"
case .ferry: "ferry"
case .heavyRail: "subway"
case .lightRail: "subway"
}
let noTrips = switch onEnum(of: noTrips) {
case .noSchedulesToday: "no service today"
case .predictionsUnavailable: "predictions unavailable"
case .serviceEndedToday: "service ended"
case nil: ""
}
logEvent(
"tapped_departure",
parameters: [
"route_id": routeId,
"stop_id": stopId,
"pinned": pinned ? "true" : "false",
"alert": alert ? "true" : "false",
"mode": mode,
"no_trips": noTrips,
]
)
}
}
15 changes: 1 addition & 14 deletions iosApp/iosApp/Analytics/NearbyTransitAnalytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
import FirebaseAnalytics
import Foundation

protocol NearbyTransitAnalytics {
protocol NearbyTransitAnalytics: DestinationRowAnalytics {
func toggledPinnedRoute(pinned: Bool, routeId: String)
func tappedDeparture(routeId: String, stopId: String, pinned: Bool, alert: Bool)
func refetchedNearbyTransit()
func tappedOnStop(stopId: String)
}
Expand All @@ -26,18 +25,6 @@ extension AnalyticsProvider: NearbyTransitAnalytics {
)
}

func tappedDeparture(routeId: String, stopId: String, pinned: Bool, alert: Bool) {
logEvent(
"tapped_departure",
parameters: [
"route_id": routeId,
"stop_id": stopId,
"pinned": pinned ? "true" : "false",
"alert": alert ? "true" : "false",
]
)
}

func refetchedNearbyTransit() {
logEvent("refetched_nearby_transit")
}
Expand Down
15 changes: 1 addition & 14 deletions iosApp/iosApp/Analytics/StopDetailsAnalytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,13 @@
import FirebaseAnalytics
import Foundation

protocol StopDetailsAnalytics {
protocol StopDetailsAnalytics: DestinationRowAnalytics {
func tappedAlertDetails(routeId: String, stopId: String, alertId: String)
func tappedDepartureRow(routeId: String, stopId: String, pinned: Bool, alert: Bool)
func tappedRouteFilter(routeId: String, stopId: String)
func toggledPinnedRouteAtStop(pinned: Bool, routeId: String)
}

extension AnalyticsProvider: StopDetailsAnalytics {
func tappedDepartureRow(routeId: String, stopId: String, pinned: Bool, alert: Bool) {
logEvent(
"tapped_departure",
parameters: [
"route_id": routeId,
"stop_id": stopId,
"pinned": pinned ? "true" : "false",
"alert": alert ? "true" : "false",
]
)
}

func tappedAlertDetails(routeId: String, stopId: String, alertId: String) {
logEvent(
"tapped_alert_details",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,21 @@
ForEach(Array(rows.enumerated()), id: \.offset) { index, row in
VStack(spacing: 0) {
OptionalNavigationLink(value: row.navigationTarget, action: { entry in
let noTrips: RealtimePatterns
.NoTripsFormat? = switch onEnum(of: row.formatted) {
case let .noTrips(noTrips): noTrips.noTripsFormat
default: nil
}
pushNavEntry(entry)
analytics.tappedDepartureRow(
analytics.tappedDeparture(
routeId: patternsByStop.routeIdentifier,
stopId: patternsByStop.stop.id,
pinned: pinned,
alert: alerts.count > 0
alert: alerts.count > 0,
routeType: patternsByStop.representativeRoute.type,
noTrips: noTrips
)
}) {

Check notice on line 230 in iosApp/iosApp/Pages/LegacyStopDetails/StopDetailsFilteredRouteView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/LegacyStopDetails/StopDetailsFilteredRouteView.swift#L230

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
HeadsignRowView(
headsign: row.headsign,
predictions: row.formatted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ struct StopDetailsRouteView: View {
condenseHeadsignPredictions: patternsByStop.routes.count > 1,
now: now,
context: .stopDetailsUnfiltered,
pushNavEntry: navAnalytics(routeId: line.id)
pushNavEntry: pushNavEntry,
analytics: analytics,
pinned: pinned
)
}
} else if let route = patternsByStop.routes.first {
Expand All @@ -36,23 +38,13 @@ struct StopDetailsRouteView: View {
condenseHeadsignPredictions: false,
now: now,
context: .stopDetailsUnfiltered,
pushNavEntry: navAnalytics(routeId: route.id)
pushNavEntry: pushNavEntry,
analytics: analytics,
pinned: pinned
)
}
} else {
EmptyView()
}
}

private func navAnalytics(routeId: String) -> (SheetNavigationStackEntry, Bool) -> Void {
{ entry, alerting in
pushNavEntry(entry)
analytics.tappedDepartureRow(
routeId: routeId,
stopId: patternsByStop.stop.id,
pinned: pinned,
alert: alerting
)
}
}
}
101 changes: 82 additions & 19 deletions iosApp/iosApp/Pages/NearbyTransit/DestinationRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,109 @@

struct DestinationRowView: View {
let patterns: RealtimePatterns
let stop: Stop
let routeId: String
let condenseHeadsignPredictions: Bool
let now: Instant
let context: TripInstantDisplay.Context
let pushNavEntry: (SheetNavigationStackEntry) -> Void
let analytics: DestinationRowAnalytics
let pinned: Bool
let routeType: RouteType

init(
patterns: RealtimePatterns,
stop: Stop,
routeId: String,
now: Instant,
context: TripInstantDisplay.Context,
condenseHeadsignPredictions: Bool = false
condenseHeadsignPredictions: Bool = false,
pushNavEntry: @escaping (SheetNavigationStackEntry) -> Void,
analytics: DestinationRowAnalytics,
pinned: Bool,
routeType: RouteType
) {
self.patterns = patterns
self.stop = stop
self.routeId = routeId
self.now = now
self.context = context
self.condenseHeadsignPredictions = condenseHeadsignPredictions
self.pushNavEntry = pushNavEntry
self.analytics = analytics
self.pinned = pinned
self.routeType = routeType
}

var body: some View {
switch onEnum(of: patterns) {
case let .byHeadsign(patternsByHeadsign):
HeadsignRowView(
headsign: patternsByHeadsign.headsign,
predictions: patternsByHeadsign.format(
now: now,
routeType: patternsByHeadsign.route.type,
count: condenseHeadsignPredictions ? 1 : 2,
context: context
),
pillDecoration: patternsByHeadsign.line != nil ?
.onRow(route: patternsByHeadsign.route) : .none
let predictions = patternsByHeadsign.format(
now: now,
routeType: patternsByHeadsign.route.type,
count: condenseHeadsignPredictions ? 1 : 2,
context: context
)
case let .byDirection(patternsByDirection):
DirectionRowView(
direction: patternsByDirection.direction,
predictions: patternsByDirection.format(
now: now,
routeType: patternsByDirection.representativeRoute.type,
context: context
SheetNavigationLink(
value: .legacyStopDetails(
stop,
.init(
routeId: routeId,
directionId: patternsByHeadsign.directionId()
)
),
pillDecoration: .onPrediction(routesByTrip: patternsByDirection.routesByTrip)
action: { entry in
pushNavEntry(entry)
analyticsTappedDeparture(predictions: predictions)
}
) {

Check notice on line 69 in iosApp/iosApp/Pages/NearbyTransit/DestinationRowView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/NearbyTransit/DestinationRowView.swift#L69

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
HeadsignRowView(
headsign: patternsByHeadsign.headsign,
predictions: predictions,
pillDecoration: patternsByHeadsign.line != nil ?
.onRow(route: patternsByHeadsign.route) : .none
)
}
case let .byDirection(patternsByDirection):
let predictions = patternsByDirection.format(
now: now,
routeType: patternsByDirection.representativeRoute.type,
context: context
)
SheetNavigationLink(
value: .legacyStopDetails(
stop,
.init(
routeId: routeId,
directionId: patternsByDirection.directionId()
)
),
action: { entry in
pushNavEntry(entry)
analyticsTappedDeparture(predictions: predictions)
}
) {

Check notice on line 95 in iosApp/iosApp/Pages/NearbyTransit/DestinationRowView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/NearbyTransit/DestinationRowView.swift#L95

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
DirectionRowView(
direction: patternsByDirection.direction,
predictions: predictions,
pillDecoration: .onPrediction(routesByTrip: patternsByDirection.routesByTrip)
)
}
}
}

private func analyticsTappedDeparture(predictions: RealtimePatterns.Format) {
let noTrips: RealtimePatterns.NoTripsFormat? = switch onEnum(of: predictions) {
case let .noTrips(noTrips): noTrips.noTripsFormat
default: nil
}
analytics.tappedDeparture(
routeId: routeId,
stopId: stop.id,
pinned: pinned,
alert: (patterns.alertsHere?.count ?? 0) > 0,
routeType: routeType,
noTrips: noTrips
)
}
}
12 changes: 3 additions & 9 deletions iosApp/iosApp/Pages/NearbyTransit/NearbyStopView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,9 @@ struct NearbyStopView: View {
condenseHeadsignPredictions: condenseHeadsignPredictions,
now: now,
context: .nearbyTransit,
pushNavEntry: { entry, alertsHere in
pushNavEntry(entry)
analytics.tappedDeparture(
routeId: patternsAtStop.routeIdentifier,
stopId: patternsAtStop.stop.id,
pinned: pinned,
alert: alertsHere
)
}
pushNavEntry: pushNavEntry,
analytics: analytics,
pinned: pinned
)
}
}
Loading
Loading