Remove debug prints and fix build warnings

- Remove all print statements from planning engine, data providers, and PDF generation
- Fix deprecated CLGeocoder usage with MKLocalSearch for iOS 26
- Fix Swift 6 actor isolation by converting PDFGenerator/ExportService to @MainActor
- Add @retroactive to CLLocationCoordinate2D protocol conformances
- Fix unused variable warnings in GameDAGRouter and scenario planners
- Remove unreachable catch blocks in SettingsViewModel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-08 13:25:27 -06:00
parent fbb5ae683e
commit 045fcd9c07
20 changed files with 188 additions and 303 deletions

View File

@@ -222,128 +222,121 @@ final class TripCreationViewModel {
viewState = .planning
do {
// Mode-specific setup
var effectiveStartDate = startDate
var effectiveEndDate = endDate
var resolvedStartLocation: LocationInput?
var resolvedEndLocation: LocationInput?
// Mode-specific setup
var effectiveStartDate = startDate
var effectiveEndDate = endDate
var resolvedStartLocation: LocationInput?
var resolvedEndLocation: LocationInput?
switch planningMode {
case .dateRange:
// Use provided date range, no location needed
// Games will be found within the date range across all regions
effectiveStartDate = startDate
effectiveEndDate = endDate
switch planningMode {
case .dateRange:
// Use provided date range, no location needed
// Games will be found within the date range across all regions
effectiveStartDate = startDate
effectiveEndDate = endDate
case .gameFirst:
// Calculate date range from selected games + buffer
if let dateRange = gameFirstDateRange {
effectiveStartDate = dateRange.start
effectiveEndDate = dateRange.end
}
// Derive start/end locations from first/last game stadiums
if let firstGame = selectedGames.sorted(by: { $0.game.dateTime < $1.game.dateTime }).first,
let lastGame = selectedGames.sorted(by: { $0.game.dateTime < $1.game.dateTime }).last {
resolvedStartLocation = LocationInput(
name: firstGame.stadium.city,
coordinate: firstGame.stadium.coordinate,
address: "\(firstGame.stadium.city), \(firstGame.stadium.state)"
)
resolvedEndLocation = LocationInput(
name: lastGame.stadium.city,
coordinate: lastGame.stadium.coordinate,
address: "\(lastGame.stadium.city), \(lastGame.stadium.state)"
)
}
case .locations:
// Resolve provided locations
await resolveLocations()
resolvedStartLocation = startLocation
resolvedEndLocation = endLocation
guard resolvedStartLocation != nil, resolvedEndLocation != nil else {
viewState = .error("Could not resolve start or end location")
return
}
case .gameFirst:
// Calculate date range from selected games + buffer
if let dateRange = gameFirstDateRange {
effectiveStartDate = dateRange.start
effectiveEndDate = dateRange.end
}
// Derive start/end locations from first/last game stadiums
if let firstGame = selectedGames.sorted(by: { $0.game.dateTime < $1.game.dateTime }).first,
let lastGame = selectedGames.sorted(by: { $0.game.dateTime < $1.game.dateTime }).last {
resolvedStartLocation = LocationInput(
name: firstGame.stadium.city,
coordinate: firstGame.stadium.coordinate,
address: "\(firstGame.stadium.city), \(firstGame.stadium.state)"
)
resolvedEndLocation = LocationInput(
name: lastGame.stadium.city,
coordinate: lastGame.stadium.coordinate,
address: "\(lastGame.stadium.city), \(lastGame.stadium.state)"
)
}
// Ensure we have games data
if games.isEmpty {
await loadScheduleData()
case .locations:
// Resolve provided locations
await resolveLocations()
resolvedStartLocation = startLocation
resolvedEndLocation = endLocation
guard resolvedStartLocation != nil, resolvedEndLocation != nil else {
viewState = .error("Could not resolve start or end location")
return
}
}
// Ensure we have games data
if games.isEmpty {
await loadScheduleData()
}
// Read max trip options from settings (default 10)
let savedMaxOptions = UserDefaults.standard.integer(forKey: "maxTripOptions")
let maxTripOptions = savedMaxOptions > 0 ? min(20, savedMaxOptions) : 10
// Build preferences
let preferences = TripPreferences(
planningMode: planningMode,
startLocation: resolvedStartLocation,
endLocation: resolvedEndLocation,
sports: selectedSports,
mustSeeGameIds: mustSeeGameIds,
travelMode: travelMode,
startDate: effectiveStartDate,
endDate: effectiveEndDate,
numberOfStops: useStopCount ? numberOfStops : nil,
tripDuration: useStopCount ? nil : tripDurationDays,
leisureLevel: leisureLevel,
mustStopLocations: mustStopLocations,
preferredCities: preferredCities,
routePreference: routePreference,
needsEVCharging: needsEVCharging,
lodgingType: lodgingType,
numberOfDrivers: numberOfDrivers,
maxDrivingHoursPerDriver: maxDrivingHoursPerDriver,
maxTripOptions: maxTripOptions
)
// Build planning request
let request = PlanningRequest(
preferences: preferences,
availableGames: games,
teams: teams,
stadiums: stadiums
)
// Plan the trip
let result = planningEngine.planItineraries(request: request)
switch result {
case .success(var options):
guard !options.isEmpty else {
viewState = .error("No valid itinerary found")
return
}
// Read max trip options from settings (default 10)
let savedMaxOptions = UserDefaults.standard.integer(forKey: "maxTripOptions")
let maxTripOptions = savedMaxOptions > 0 ? min(20, savedMaxOptions) : 10
// Build preferences
let preferences = TripPreferences(
planningMode: planningMode,
startLocation: resolvedStartLocation,
endLocation: resolvedEndLocation,
sports: selectedSports,
mustSeeGameIds: mustSeeGameIds,
travelMode: travelMode,
startDate: effectiveStartDate,
endDate: effectiveEndDate,
numberOfStops: useStopCount ? numberOfStops : nil,
tripDuration: useStopCount ? nil : tripDurationDays,
leisureLevel: leisureLevel,
mustStopLocations: mustStopLocations,
preferredCities: preferredCities,
routePreference: routePreference,
needsEVCharging: needsEVCharging,
lodgingType: lodgingType,
numberOfDrivers: numberOfDrivers,
maxDrivingHoursPerDriver: maxDrivingHoursPerDriver,
maxTripOptions: maxTripOptions
)
// Build planning request
let request = PlanningRequest(
preferences: preferences,
availableGames: games,
teams: teams,
stadiums: stadiums
)
// Plan the trip
let result = planningEngine.planItineraries(request: request)
switch result {
case .success(var options):
guard !options.isEmpty else {
viewState = .error("No valid itinerary found")
return
}
// Enrich with EV chargers if requested and feature is enabled
if FeatureFlags.enableEVCharging && needsEVCharging {
print("[TripCreation] Enriching \(options.count) options with EV chargers...")
options = await ItineraryBuilder.enrichWithEVChargers(options)
print("[TripCreation] EV charger enrichment complete")
}
// Store preferences for later conversion
currentPreferences = preferences
if options.count == 1 {
// Only one option - go directly to detail
let trip = convertToTrip(option: options[0], preferences: preferences)
viewState = .completed(trip)
} else {
// Multiple options - show selection view
viewState = .selectingOption(options)
}
case .failure(let failure):
viewState = .error(failureMessage(for: failure))
// Enrich with EV chargers if requested and feature is enabled
if FeatureFlags.enableEVCharging && needsEVCharging {
options = await ItineraryBuilder.enrichWithEVChargers(options)
}
} catch {
viewState = .error("Trip planning failed: \(error.localizedDescription)")
// Store preferences for later conversion
currentPreferences = preferences
if options.count == 1 {
// Only one option - go directly to detail
let trip = convertToTrip(option: options[0], preferences: preferences)
viewState = .completed(trip)
} else {
// Multiple options - show selection view
viewState = .selectingOption(options)
}
case .failure(let failure):
viewState = .error(failureMessage(for: failure))
}
}

View File

@@ -62,9 +62,7 @@ struct TripDetailView: View {
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
Button {
Task {
await shareTrip()
}
shareTrip()
} label: {
Image(systemName: "square.and.arrow.up")
.foregroundStyle(Theme.warmOrange)
@@ -429,8 +427,10 @@ struct TripDetailView: View {
let destination = stops[i + 1]
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: source.coordinate))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: destination.coordinate))
let sourceLocation = CLLocation(latitude: source.coordinate.latitude, longitude: source.coordinate.longitude)
let destLocation = CLLocation(latitude: destination.coordinate.latitude, longitude: destination.coordinate.longitude)
request.source = MKMapItem(location: sourceLocation, address: nil)
request.destination = MKMapItem(location: destLocation, address: nil)
request.transportType = .automobile
let directions = MKDirections(request: request)
@@ -504,14 +504,14 @@ struct TripDetailView: View {
exportURL = url
showExportSheet = true
} catch {
print("Failed to export PDF: \(error)")
// PDF export failed silently
}
isExporting = false
}
private func shareTrip() async {
shareURL = await exportService.shareTrip(trip)
private func shareTrip() {
shareURL = exportService.shareTrip(trip)
showShareSheet = true
}
@@ -525,7 +525,6 @@ struct TripDetailView: View {
private func saveTrip() {
guard let savedTrip = SavedTrip.from(trip, games: games, status: .planned) else {
print("Failed to create SavedTrip")
return
}
@@ -537,7 +536,7 @@ struct TripDetailView: View {
isSaved = true
}
} catch {
print("Failed to save trip: \(error)")
// Save failed silently
}
}
@@ -557,7 +556,7 @@ struct TripDetailView: View {
isSaved = false
}
} catch {
print("Failed to unsave trip: \(error)")
// Unsave failed silently
}
}