888943deb4
New top-level TabView (RootView) splits the app into: Tab 1 (Search): existing RoutePlannerView home Tab 2 (Live): live flight tracker Live tab features: - MapKit map showing every aircraft in the visible viewport, rotated to true heading. Color-coded by vertical state: climbing/level/ descending/on-ground. - Auto-refresh every 15s + on map pan/zoom (debounced); manual refresh button. Rate-limit aware (60s backoff on HTTP 429). - Tap any aircraft → modal sheet with live state grid (altitude, speed, heading, vertical rate, squawk, last-contact), current route (lazily fetched per-aircraft from OpenSky's /flights/ aircraft endpoint, mapped from ICAO to IATA airport codes), and recent flight history (up to 8 prior legs). - Filters: airline (multi-select from currently visible callsigns, with counts), aircraft type (ADS-B emitter category), airborne- only toggle. All filters render as horizontal chips and clear with a single tap. - Search bar: callsign/flight number — submitting centers the map on the match and opens its detail sheet. Data source: OpenSky Network REST API. Free, anonymous (~100 req/ day cap), JSON. Same ADS-B data FR24 starts with — without satellite ADS-B coverage but more than enough for the in-flight tracker use case. Reviewed FR24's APK and confirmed they migrated their live feed to gRPC+protobuf with anti-bot device-id headers; OpenSky's plain JSON is the right tradeoff for our build. Implementation: - LiveAircraft model: decodes OpenSky's mixed-type position arrays into a typed struct; computed properties for ft/knots/heading and airline ICAO extracted from callsign. - OpenSkyClient: actor with /states/all + /flights/aircraft. Bbox query, throttle-aware errors. - AircraftRegistry: ~80 ICAO → (IATA, name) entries for the major carriers; everything else falls through to the raw ICAO code. - LiveFlightsView: the main map + filter UI. - LiveFlightDetailSheet: tap modal with live state + route history. - RootView: TabView wrapping RoutePlannerView (Search) and the new LiveFlightsView (Live). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
586 lines
33 KiB
Plaintext
586 lines
33 KiB
Plaintext
// !$*UTF8*$!
|
|
{
|
|
archiveVersion = 1;
|
|
classes = {
|
|
};
|
|
objectVersion = 56;
|
|
objects = {
|
|
|
|
/* Begin PBXBuildFile section */
|
|
019A3D900D1B4145AB87B9F7 /* MapAirport.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1AC05BFDFDE4A94B360EB05 /* MapAirport.swift */; };
|
|
0E02E6501AA249229BBC335A /* Route.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFE025789164A779FC980B0 /* Route.swift */; };
|
|
1FA279998CFB44949B4188FE /* FlightService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A65682BD902141BAA686D101 /* FlightService.swift */; };
|
|
2C3FF395E0724FA5A6E33C3A /* FlightScheduleRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9640481120A418EBCD3CE73 /* FlightScheduleRow.swift */; };
|
|
303821C9668A44F38FFA02CA /* AirportSearchField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD303E3EDCC4BF2BCF31722 /* AirportSearchField.swift */; };
|
|
35D016EBA93C40BB873AB304 /* Airline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AC23D8748D42C9A7115FAC /* Airline.swift */; };
|
|
4C770C55CB3643BAB7B9D622 /* AirportBrowserSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15676B4BD35745D1BD1DC947 /* AirportBrowserSheet.swift */; };
|
|
61F8E3DD7D434DA7854C20E2 /* FlightsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D822B4ABF741F890A4400C /* FlightsApp.swift */; };
|
|
6558A31ADEC740FC8C56EA22 /* FlightSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B913D04A4E51436595308A21 /* FlightSchedule.swift */; };
|
|
7FFD9A2D25F9421D8929C027 /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36862683C4F44A95AFE234EB /* SearchViewModel.swift */; };
|
|
80D2BC95002A4931B3C10B4C /* airports.json in Resources */ = {isa = PBXBuildFile; fileRef = 53F457716F0642BDBCBA93EA /* airports.json */; };
|
|
9C1300E497B049FE8DA677E0 /* RouteDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434DEB1EB08F4F0CBCB91266 /* RouteDetailViewModel.swift */; };
|
|
BADBC95A6A6D4267A01DA898 /* AirportDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58C339D6084657B0538E9C /* AirportDatabase.swift */; };
|
|
BB3E647E4A07477F9F37E607 /* RouteDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C1176F877BF496ABF079040 /* RouteDetailView.swift */; };
|
|
C36C490556254AC88EC02C80 /* DestinationsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEAC0EBABFD41569FE69B1B /* DestinationsViewModel.swift */; };
|
|
C7191E4E1AF84FECAD27CEC9 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7987BD4832D44F1A0851933 /* Country.swift */; };
|
|
D0EC717347974D668C77B9D2 /* DestinationsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300153508F8445B6A78CEC52 /* DestinationsListView.swift */; };
|
|
E41FC265B0994D2ABC4DDE67 /* Airport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EC89DEE12942B49DF51984 /* Airport.swift */; };
|
|
F79789179F4443FD859BDEF0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D9E26DCDE2904210ABCA7855 /* Assets.xcassets */; };
|
|
FD853F72EE724922B0E4E235 /* AirportMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C2EB471F011450DA7BBEFAD /* AirportMapView.swift */; };
|
|
FF74A792115C414CA9AB5B36 /* BrowseAirport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4944338B20BA4AB98F05D4F7 /* BrowseAirport.swift */; };
|
|
AA1111111111111111111111 /* FlightTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2222222222222222222222 /* FlightTheme.swift */; };
|
|
AA3333333333333333333333 /* RouteVisualization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4444444444444444444444 /* RouteVisualization.swift */; };
|
|
BB1100001111000011110001 /* FlightLoad.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1100001111000011110002 /* FlightLoad.swift */; };
|
|
BB1100001111000011110003 /* AirlineLoadService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1100001111000011110004 /* AirlineLoadService.swift */; };
|
|
BB1100001111000011110005 /* FlightLoadDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1100001111000011110006 /* FlightLoadDetailView.swift */; };
|
|
D3AFA3F4A9AF4CA4BD2BA5BE /* FavoriteRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59848F598CC941C393B23604 /* FavoriteRoute.swift */; };
|
|
AB9AB52419104B73A81B81A8 /* FavoritesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44E75295BB044D13AD26563D /* FavoritesManager.swift */; };
|
|
E62A922EC7924273BDF14005 /* RouteMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2574CDD727284621BBB56145 /* RouteMapView.swift */; };
|
|
9124DA69A89F4E90A35DD13C /* WebViewFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22867394CDCC423891007AE1 /* WebViewFetcher.swift */; };
|
|
BB2200002222000022220001 /* JSXWebViewFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2200002222000022220002 /* JSXWebViewFetcher.swift */; };
|
|
RE1100001111000011110001 /* RouteExplorerModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE1100001111000011110002 /* RouteExplorerModels.swift */; };
|
|
RE2200002222000022220001 /* RouteExplorerClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE2200002222000022220002 /* RouteExplorerClient.swift */; };
|
|
RE3300003333000033330001 /* RoutePlannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE3300003333000033330002 /* RoutePlannerView.swift */; };
|
|
RE5500005555000055550001 /* IATAAirportPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE5500005555000055550002 /* IATAAirportPicker.swift */; };
|
|
RE6600006666000066660001 /* ConnectionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE6600006666000066660002 /* ConnectionRow.swift */; };
|
|
RE7700007777000077770001 /* ConnectionLoadDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE7700007777000077770002 /* ConnectionLoadDetailView.swift */; };
|
|
RE8800008888000088880001 /* SearchRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = RE8800008888000088880002 /* SearchRoute.swift */; };
|
|
T1000000000000000000001A /* AirlineLoadIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = T1000000000000000000001B /* AirlineLoadIntegrationTests.swift */; };
|
|
LV1100001111000011110001 /* LiveAircraft.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV1100001111000011110002 /* LiveAircraft.swift */; };
|
|
LV2200002222000022220001 /* OpenSkyClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV2200002222000022220002 /* OpenSkyClient.swift */; };
|
|
LV3300003333000033330001 /* AircraftRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV3300003333000033330002 /* AircraftRegistry.swift */; };
|
|
LV4400004444000044440001 /* LiveFlightsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV4400004444000044440002 /* LiveFlightsView.swift */; };
|
|
LV5500005555000055550001 /* LiveFlightDetailSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV5500005555000055550002 /* LiveFlightDetailSheet.swift */; };
|
|
LV6600006666000066660001 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = LV6600006666000066660002 /* RootView.swift */; };
|
|
/* End PBXBuildFile section */
|
|
|
|
/* Begin PBXContainerItemProxy section */
|
|
T1000000000000000000002A /* PBXContainerItemProxy */ = {
|
|
isa = PBXContainerItemProxy;
|
|
containerPortal = 5418BEEAEFF644ADA7240CEA /* Project object */;
|
|
proxyType = 1;
|
|
remoteGlobalIDString = E373C48C497D48D388BF7657;
|
|
remoteInfo = Flights;
|
|
};
|
|
/* End PBXContainerItemProxy section */
|
|
|
|
/* Begin PBXFileReference section */
|
|
04AC23D8748D42C9A7115FAC /* Airline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Airline.swift; sourceTree = "<group>"; };
|
|
0CD303E3EDCC4BF2BCF31722 /* AirportSearchField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirportSearchField.swift; sourceTree = "<group>"; };
|
|
0EFE025789164A779FC980B0 /* Route.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Route.swift; sourceTree = "<group>"; };
|
|
15676B4BD35745D1BD1DC947 /* AirportBrowserSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirportBrowserSheet.swift; sourceTree = "<group>"; };
|
|
1C1176F877BF496ABF079040 /* RouteDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteDetailView.swift; sourceTree = "<group>"; };
|
|
300153508F8445B6A78CEC52 /* DestinationsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationsListView.swift; sourceTree = "<group>"; };
|
|
36862683C4F44A95AFE234EB /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = "<group>"; };
|
|
434DEB1EB08F4F0CBCB91266 /* RouteDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteDetailViewModel.swift; sourceTree = "<group>"; };
|
|
4944338B20BA4AB98F05D4F7 /* BrowseAirport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowseAirport.swift; sourceTree = "<group>"; };
|
|
53F457716F0642BDBCBA93EA /* airports.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = airports.json; sourceTree = "<group>"; };
|
|
7C2EB471F011450DA7BBEFAD /* AirportMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirportMapView.swift; sourceTree = "<group>"; };
|
|
85EC89DEE12942B49DF51984 /* Airport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Airport.swift; sourceTree = "<group>"; };
|
|
8A3CB0CCC2524542AFB0D1D2 /* Flights.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Flights.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
9A58C339D6084657B0538E9C /* AirportDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirportDatabase.swift; sourceTree = "<group>"; };
|
|
9BEAC0EBABFD41569FE69B1B /* DestinationsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationsViewModel.swift; sourceTree = "<group>"; };
|
|
A65682BD902141BAA686D101 /* FlightService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightService.swift; sourceTree = "<group>"; };
|
|
B913D04A4E51436595308A21 /* FlightSchedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightSchedule.swift; sourceTree = "<group>"; };
|
|
D9E26DCDE2904210ABCA7855 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
|
E1AC05BFDFDE4A94B360EB05 /* MapAirport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAirport.swift; sourceTree = "<group>"; };
|
|
E6D822B4ABF741F890A4400C /* FlightsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightsApp.swift; sourceTree = "<group>"; };
|
|
E7987BD4832D44F1A0851933 /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = "<group>"; };
|
|
F9640481120A418EBCD3CE73 /* FlightScheduleRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightScheduleRow.swift; sourceTree = "<group>"; };
|
|
AA2222222222222222222222 /* FlightTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightTheme.swift; sourceTree = "<group>"; };
|
|
AA4444444444444444444444 /* RouteVisualization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteVisualization.swift; sourceTree = "<group>"; };
|
|
BB1100001111000011110002 /* FlightLoad.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightLoad.swift; sourceTree = "<group>"; };
|
|
BB1100001111000011110004 /* AirlineLoadService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirlineLoadService.swift; sourceTree = "<group>"; };
|
|
BB1100001111000011110006 /* FlightLoadDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlightLoadDetailView.swift; sourceTree = "<group>"; };
|
|
59848F598CC941C393B23604 /* FavoriteRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteRoute.swift; sourceTree = "<group>"; };
|
|
44E75295BB044D13AD26563D /* FavoritesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesManager.swift; sourceTree = "<group>"; };
|
|
2574CDD727284621BBB56145 /* RouteMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteMapView.swift; sourceTree = "<group>"; };
|
|
22867394CDCC423891007AE1 /* WebViewFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewFetcher.swift; sourceTree = "<group>"; };
|
|
BB2200002222000022220002 /* JSXWebViewFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSXWebViewFetcher.swift; sourceTree = "<group>"; };
|
|
RE1100001111000011110002 /* RouteExplorerModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteExplorerModels.swift; sourceTree = "<group>"; };
|
|
RE2200002222000022220002 /* RouteExplorerClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteExplorerClient.swift; sourceTree = "<group>"; };
|
|
RE3300003333000033330002 /* RoutePlannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutePlannerView.swift; sourceTree = "<group>"; };
|
|
RE5500005555000055550002 /* IATAAirportPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IATAAirportPicker.swift; sourceTree = "<group>"; };
|
|
RE6600006666000066660002 /* ConnectionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionRow.swift; sourceTree = "<group>"; };
|
|
RE7700007777000077770002 /* ConnectionLoadDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionLoadDetailView.swift; sourceTree = "<group>"; };
|
|
RE8800008888000088880002 /* SearchRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRoute.swift; sourceTree = "<group>"; };
|
|
T1000000000000000000001B /* AirlineLoadIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirlineLoadIntegrationTests.swift; sourceTree = "<group>"; };
|
|
T1000000000000000000003A /* FlightsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlightsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
LV1100001111000011110002 /* LiveAircraft.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveAircraft.swift; sourceTree = "<group>"; };
|
|
LV2200002222000022220002 /* OpenSkyClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSkyClient.swift; sourceTree = "<group>"; };
|
|
LV3300003333000033330002 /* AircraftRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AircraftRegistry.swift; sourceTree = "<group>"; };
|
|
LV4400004444000044440002 /* LiveFlightsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveFlightsView.swift; sourceTree = "<group>"; };
|
|
LV5500005555000055550002 /* LiveFlightDetailSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveFlightDetailSheet.swift; sourceTree = "<group>"; };
|
|
LV6600006666000066660002 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
|
|
/* End PBXFileReference section */
|
|
|
|
/* Begin PBXFrameworksBuildPhase section */
|
|
EB782B062CA144E2972778DE /* Frameworks */ = {
|
|
isa = PBXFrameworksBuildPhase;
|
|
buildActionMask = 2147483647;
|
|
files = (
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
T1000000000000000000004A /* Frameworks */ = {
|
|
isa = PBXFrameworksBuildPhase;
|
|
buildActionMask = 2147483647;
|
|
files = (
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
/* End PBXFrameworksBuildPhase section */
|
|
|
|
/* Begin PBXGroup section */
|
|
1B20C5393D8F432A93097C2C /* Views */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
0CD303E3EDCC4BF2BCF31722 /* AirportSearchField.swift */,
|
|
300153508F8445B6A78CEC52 /* DestinationsListView.swift */,
|
|
1C1176F877BF496ABF079040 /* RouteDetailView.swift */,
|
|
2574CDD727284621BBB56145 /* RouteMapView.swift */,
|
|
F9640481120A418EBCD3CE73 /* FlightScheduleRow.swift */,
|
|
7C2EB471F011450DA7BBEFAD /* AirportMapView.swift */,
|
|
15676B4BD35745D1BD1DC947 /* AirportBrowserSheet.swift */,
|
|
BB1100001111000011110006 /* FlightLoadDetailView.swift */,
|
|
RE3300003333000033330002 /* RoutePlannerView.swift */,
|
|
RE7700007777000077770002 /* ConnectionLoadDetailView.swift */,
|
|
LV4400004444000044440002 /* LiveFlightsView.swift */,
|
|
LV5500005555000055550002 /* LiveFlightDetailSheet.swift */,
|
|
LV6600006666000066660002 /* RootView.swift */,
|
|
AA5555555555555555555555 /* Styles */,
|
|
AA6666666666666666666666 /* Components */,
|
|
);
|
|
path = Views;
|
|
sourceTree = "<group>";
|
|
};
|
|
AA5555555555555555555555 /* Styles */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
AA2222222222222222222222 /* FlightTheme.swift */,
|
|
);
|
|
path = Styles;
|
|
sourceTree = "<group>";
|
|
};
|
|
AA6666666666666666666666 /* Components */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
AA4444444444444444444444 /* RouteVisualization.swift */,
|
|
RE5500005555000055550002 /* IATAAirportPicker.swift */,
|
|
RE6600006666000066660002 /* ConnectionRow.swift */,
|
|
);
|
|
path = Components;
|
|
sourceTree = "<group>";
|
|
};
|
|
1D5A2C06B99046F3934D2E59 /* Flights */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
E6D822B4ABF741F890A4400C /* FlightsApp.swift */,
|
|
F35FEFCEEAC24D248AC81678 /* Models */,
|
|
B6019ED81F39462B92BDC856 /* Services */,
|
|
6E94DB5F9EB345948E2D5E2A /* ViewModels */,
|
|
1B20C5393D8F432A93097C2C /* Views */,
|
|
D9E26DCDE2904210ABCA7855 /* Assets.xcassets */,
|
|
53F457716F0642BDBCBA93EA /* airports.json */,
|
|
);
|
|
path = Flights;
|
|
sourceTree = "<group>";
|
|
};
|
|
517CC07B82D949359C6CD4F5 /* Products */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
8A3CB0CCC2524542AFB0D1D2 /* Flights.app */,
|
|
T1000000000000000000003A /* FlightsTests.xctest */,
|
|
);
|
|
name = Products;
|
|
sourceTree = "<group>";
|
|
};
|
|
T1000000000000000000005A /* FlightsTests */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
T1000000000000000000001B /* AirlineLoadIntegrationTests.swift */,
|
|
);
|
|
path = FlightsTests;
|
|
sourceTree = "<group>";
|
|
};
|
|
6E94DB5F9EB345948E2D5E2A /* ViewModels */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
36862683C4F44A95AFE234EB /* SearchViewModel.swift */,
|
|
9BEAC0EBABFD41569FE69B1B /* DestinationsViewModel.swift */,
|
|
434DEB1EB08F4F0CBCB91266 /* RouteDetailViewModel.swift */,
|
|
);
|
|
path = ViewModels;
|
|
sourceTree = "<group>";
|
|
};
|
|
B6019ED81F39462B92BDC856 /* Services */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
A65682BD902141BAA686D101 /* FlightService.swift */,
|
|
22867394CDCC423891007AE1 /* WebViewFetcher.swift */,
|
|
44E75295BB044D13AD26563D /* FavoritesManager.swift */,
|
|
9A58C339D6084657B0538E9C /* AirportDatabase.swift */,
|
|
BB1100001111000011110004 /* AirlineLoadService.swift */,
|
|
BB2200002222000022220002 /* JSXWebViewFetcher.swift */,
|
|
RE2200002222000022220002 /* RouteExplorerClient.swift */,
|
|
LV2200002222000022220002 /* OpenSkyClient.swift */,
|
|
LV3300003333000033330002 /* AircraftRegistry.swift */,
|
|
);
|
|
path = Services;
|
|
sourceTree = "<group>";
|
|
};
|
|
EDB9BC1CC7104FB58C275091 = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
1D5A2C06B99046F3934D2E59 /* Flights */,
|
|
T1000000000000000000005A /* FlightsTests */,
|
|
517CC07B82D949359C6CD4F5 /* Products */,
|
|
);
|
|
sourceTree = "<group>";
|
|
};
|
|
F35FEFCEEAC24D248AC81678 /* Models */ = {
|
|
isa = PBXGroup;
|
|
children = (
|
|
85EC89DEE12942B49DF51984 /* Airport.swift */,
|
|
04AC23D8748D42C9A7115FAC /* Airline.swift */,
|
|
0EFE025789164A779FC980B0 /* Route.swift */,
|
|
B913D04A4E51436595308A21 /* FlightSchedule.swift */,
|
|
59848F598CC941C393B23604 /* FavoriteRoute.swift */,
|
|
E1AC05BFDFDE4A94B360EB05 /* MapAirport.swift */,
|
|
4944338B20BA4AB98F05D4F7 /* BrowseAirport.swift */,
|
|
E7987BD4832D44F1A0851933 /* Country.swift */,
|
|
BB1100001111000011110002 /* FlightLoad.swift */,
|
|
RE1100001111000011110002 /* RouteExplorerModels.swift */,
|
|
RE8800008888000088880002 /* SearchRoute.swift */,
|
|
LV1100001111000011110002 /* LiveAircraft.swift */,
|
|
);
|
|
path = Models;
|
|
sourceTree = "<group>";
|
|
};
|
|
/* End PBXGroup section */
|
|
|
|
/* Begin PBXNativeTarget section */
|
|
E373C48C497D48D388BF7657 /* Flights */ = {
|
|
isa = PBXNativeTarget;
|
|
buildConfigurationList = 2E22AD8D30AA4AF593618EDA /* Build configuration list for PBXNativeTarget "Flights" */;
|
|
buildPhases = (
|
|
A5535283EA784250AAF50064 /* Sources */,
|
|
EB782B062CA144E2972778DE /* Frameworks */,
|
|
6B9FCA84AAAA44529A95D7AC /* Resources */,
|
|
);
|
|
buildRules = (
|
|
);
|
|
dependencies = (
|
|
);
|
|
name = Flights;
|
|
productName = Flights;
|
|
productReference = 8A3CB0CCC2524542AFB0D1D2 /* Flights.app */;
|
|
productType = "com.apple.product-type.application";
|
|
};
|
|
T1000000000000000000006A /* FlightsTests */ = {
|
|
isa = PBXNativeTarget;
|
|
buildConfigurationList = T1000000000000000000007A /* Build configuration list for PBXNativeTarget "FlightsTests" */;
|
|
buildPhases = (
|
|
T1000000000000000000008A /* Sources */,
|
|
T1000000000000000000004A /* Frameworks */,
|
|
);
|
|
buildRules = (
|
|
);
|
|
dependencies = (
|
|
T1000000000000000000009A /* PBXTargetDependency */,
|
|
);
|
|
name = FlightsTests;
|
|
productName = FlightsTests;
|
|
productReference = T1000000000000000000003A /* FlightsTests.xctest */;
|
|
productType = "com.apple.product-type.bundle.unit-test";
|
|
};
|
|
/* End PBXNativeTarget section */
|
|
|
|
/* Begin PBXProject section */
|
|
5418BEEAEFF644ADA7240CEA /* Project object */ = {
|
|
isa = PBXProject;
|
|
attributes = {
|
|
BuildIndependentTargetsInParallel = 1;
|
|
LastSwiftUpdateCheck = 1540;
|
|
LastUpgradeCheck = 1540;
|
|
};
|
|
buildConfigurationList = AD1FB003D80641D59E37D6A0 /* Build configuration list for PBXProject "Flights" */;
|
|
compatibilityVersion = "Xcode 14.0";
|
|
developmentRegion = en;
|
|
hasScannedForEncodings = 0;
|
|
knownRegions = (
|
|
en,
|
|
Base,
|
|
);
|
|
mainGroup = EDB9BC1CC7104FB58C275091;
|
|
productRefGroup = 517CC07B82D949359C6CD4F5 /* Products */;
|
|
projectDirPath = "";
|
|
projectRoot = "";
|
|
targets = (
|
|
E373C48C497D48D388BF7657 /* Flights */,
|
|
T1000000000000000000006A /* FlightsTests */,
|
|
);
|
|
};
|
|
/* End PBXProject section */
|
|
|
|
/* Begin PBXTargetDependency section */
|
|
T1000000000000000000009A /* PBXTargetDependency */ = {
|
|
isa = PBXTargetDependency;
|
|
target = E373C48C497D48D388BF7657 /* Flights */;
|
|
targetProxy = T1000000000000000000002A /* PBXContainerItemProxy */;
|
|
};
|
|
/* End PBXTargetDependency section */
|
|
|
|
/* Begin PBXResourcesBuildPhase section */
|
|
6B9FCA84AAAA44529A95D7AC /* Resources */ = {
|
|
isa = PBXResourcesBuildPhase;
|
|
buildActionMask = 2147483647;
|
|
files = (
|
|
F79789179F4443FD859BDEF0 /* Assets.xcassets in Resources */,
|
|
80D2BC95002A4931B3C10B4C /* airports.json in Resources */,
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
/* End PBXResourcesBuildPhase section */
|
|
|
|
/* Begin PBXSourcesBuildPhase section */
|
|
A5535283EA784250AAF50064 /* Sources */ = {
|
|
isa = PBXSourcesBuildPhase;
|
|
buildActionMask = 2147483647;
|
|
files = (
|
|
61F8E3DD7D434DA7854C20E2 /* FlightsApp.swift in Sources */,
|
|
E41FC265B0994D2ABC4DDE67 /* Airport.swift in Sources */,
|
|
35D016EBA93C40BB873AB304 /* Airline.swift in Sources */,
|
|
0E02E6501AA249229BBC335A /* Route.swift in Sources */,
|
|
6558A31ADEC740FC8C56EA22 /* FlightSchedule.swift in Sources */,
|
|
1FA279998CFB44949B4188FE /* FlightService.swift in Sources */,
|
|
7FFD9A2D25F9421D8929C027 /* SearchViewModel.swift in Sources */,
|
|
C36C490556254AC88EC02C80 /* DestinationsViewModel.swift in Sources */,
|
|
9C1300E497B049FE8DA677E0 /* RouteDetailViewModel.swift in Sources */,
|
|
303821C9668A44F38FFA02CA /* AirportSearchField.swift in Sources */,
|
|
D0EC717347974D668C77B9D2 /* DestinationsListView.swift in Sources */,
|
|
BB3E647E4A07477F9F37E607 /* RouteDetailView.swift in Sources */,
|
|
2C3FF395E0724FA5A6E33C3A /* FlightScheduleRow.swift in Sources */,
|
|
C7191E4E1AF84FECAD27CEC9 /* Country.swift in Sources */,
|
|
FF74A792115C414CA9AB5B36 /* BrowseAirport.swift in Sources */,
|
|
4C770C55CB3643BAB7B9D622 /* AirportBrowserSheet.swift in Sources */,
|
|
019A3D900D1B4145AB87B9F7 /* MapAirport.swift in Sources */,
|
|
BADBC95A6A6D4267A01DA898 /* AirportDatabase.swift in Sources */,
|
|
FD853F72EE724922B0E4E235 /* AirportMapView.swift in Sources */,
|
|
AA1111111111111111111111 /* FlightTheme.swift in Sources */,
|
|
AA3333333333333333333333 /* RouteVisualization.swift in Sources */,
|
|
BB1100001111000011110001 /* FlightLoad.swift in Sources */,
|
|
BB1100001111000011110003 /* AirlineLoadService.swift in Sources */,
|
|
BB1100001111000011110005 /* FlightLoadDetailView.swift in Sources */,
|
|
D3AFA3F4A9AF4CA4BD2BA5BE /* FavoriteRoute.swift in Sources */,
|
|
AB9AB52419104B73A81B81A8 /* FavoritesManager.swift in Sources */,
|
|
E62A922EC7924273BDF14005 /* RouteMapView.swift in Sources */,
|
|
9124DA69A89F4E90A35DD13C /* WebViewFetcher.swift in Sources */,
|
|
BB2200002222000022220001 /* JSXWebViewFetcher.swift in Sources */,
|
|
RE1100001111000011110001 /* RouteExplorerModels.swift in Sources */,
|
|
RE2200002222000022220001 /* RouteExplorerClient.swift in Sources */,
|
|
RE3300003333000033330001 /* RoutePlannerView.swift in Sources */,
|
|
RE5500005555000055550001 /* IATAAirportPicker.swift in Sources */,
|
|
RE6600006666000066660001 /* ConnectionRow.swift in Sources */,
|
|
RE7700007777000077770001 /* ConnectionLoadDetailView.swift in Sources */,
|
|
RE8800008888000088880001 /* SearchRoute.swift in Sources */,
|
|
LV1100001111000011110001 /* LiveAircraft.swift in Sources */,
|
|
LV2200002222000022220001 /* OpenSkyClient.swift in Sources */,
|
|
LV3300003333000033330001 /* AircraftRegistry.swift in Sources */,
|
|
LV4400004444000044440001 /* LiveFlightsView.swift in Sources */,
|
|
LV5500005555000055550001 /* LiveFlightDetailSheet.swift in Sources */,
|
|
LV6600006666000066660001 /* RootView.swift in Sources */,
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
T1000000000000000000008A /* Sources */ = {
|
|
isa = PBXSourcesBuildPhase;
|
|
buildActionMask = 2147483647;
|
|
files = (
|
|
T1000000000000000000001A /* AirlineLoadIntegrationTests.swift in Sources */,
|
|
);
|
|
runOnlyForDeploymentPostprocessing = 0;
|
|
};
|
|
/* End PBXSourcesBuildPhase section */
|
|
|
|
/* Begin XCBuildConfiguration section */
|
|
1A8450A5FFF54054AB64D72A /* Release */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
CODE_SIGN_STYLE = Automatic;
|
|
CURRENT_PROJECT_VERSION = 1;
|
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
|
GENERATE_INFOPLIST_FILE = YES;
|
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
LD_RUNPATH_SEARCH_PATHS = (
|
|
"$(inherited)",
|
|
"@executable_path/Frameworks",
|
|
);
|
|
MARKETING_VERSION = 1.0;
|
|
PRODUCT_BUNDLE_IDENTIFIER = com.flights.app;
|
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
|
SUPPORTS_MACCATALYST = NO;
|
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
SWIFT_VERSION = 5.0;
|
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
};
|
|
name = Release;
|
|
};
|
|
2013CC286F244D4EB2F6844E /* Debug */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
|
CODE_SIGN_STYLE = Automatic;
|
|
CURRENT_PROJECT_VERSION = 1;
|
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
|
GENERATE_INFOPLIST_FILE = YES;
|
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
|
LD_RUNPATH_SEARCH_PATHS = (
|
|
"$(inherited)",
|
|
"@executable_path/Frameworks",
|
|
);
|
|
MARKETING_VERSION = 1.0;
|
|
PRODUCT_BUNDLE_IDENTIFIER = com.flights.app;
|
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
|
SUPPORTS_MACCATALYST = NO;
|
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
|
SWIFT_VERSION = 5.0;
|
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
};
|
|
name = Debug;
|
|
};
|
|
586CEED6298F48F5A36032EC /* Release */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
CLANG_ANALYZER_NONNULL = YES;
|
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
CLANG_ENABLE_MODULES = YES;
|
|
CLANG_ENABLE_OBJC_ARC = YES;
|
|
COPY_PHASE_STRIP = NO;
|
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
ENABLE_NS_ASSERTIONS = NO;
|
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
|
MTL_ENABLE_DEBUG_INFO = NO;
|
|
MTL_FAST_MATH = YES;
|
|
SDKROOT = iphoneos;
|
|
SWIFT_COMPILATION_MODE = wholemodule;
|
|
VALIDATE_PRODUCT = YES;
|
|
};
|
|
name = Release;
|
|
};
|
|
CE9F5DD65F2043CB9B39FC35 /* Debug */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
CLANG_ANALYZER_NONNULL = YES;
|
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
|
CLANG_ENABLE_MODULES = YES;
|
|
CLANG_ENABLE_OBJC_ARC = YES;
|
|
COPY_PHASE_STRIP = NO;
|
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
ENABLE_TESTABILITY = YES;
|
|
GCC_DYNAMIC_NO_PIC = NO;
|
|
GCC_OPTIMIZATION_LEVEL = 0;
|
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
"DEBUG=1",
|
|
"$(inherited)",
|
|
);
|
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
|
MTL_FAST_MATH = YES;
|
|
ONLY_ACTIVE_ARCH = YES;
|
|
SDKROOT = iphoneos;
|
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
};
|
|
name = Debug;
|
|
};
|
|
T100000000000000000000BA /* Debug */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
|
CODE_SIGN_STYLE = Automatic;
|
|
CURRENT_PROJECT_VERSION = 1;
|
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
|
GENERATE_INFOPLIST_FILE = YES;
|
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
|
MARKETING_VERSION = 1.0;
|
|
PRODUCT_BUNDLE_IDENTIFIER = com.flights.app.FlightsTests;
|
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
|
SWIFT_VERSION = 5.0;
|
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Flights.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Flights";
|
|
};
|
|
name = Debug;
|
|
};
|
|
T100000000000000000000CA /* Release */ = {
|
|
isa = XCBuildConfiguration;
|
|
buildSettings = {
|
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
|
CODE_SIGN_STYLE = Automatic;
|
|
CURRENT_PROJECT_VERSION = 1;
|
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
|
GENERATE_INFOPLIST_FILE = YES;
|
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
|
MARKETING_VERSION = 1.0;
|
|
PRODUCT_BUNDLE_IDENTIFIER = com.flights.app.FlightsTests;
|
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
|
SWIFT_VERSION = 5.0;
|
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Flights.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Flights";
|
|
};
|
|
name = Release;
|
|
};
|
|
/* End XCBuildConfiguration section */
|
|
|
|
/* Begin XCConfigurationList section */
|
|
2E22AD8D30AA4AF593618EDA /* Build configuration list for PBXNativeTarget "Flights" */ = {
|
|
isa = XCConfigurationList;
|
|
buildConfigurations = (
|
|
2013CC286F244D4EB2F6844E /* Debug */,
|
|
1A8450A5FFF54054AB64D72A /* Release */,
|
|
);
|
|
defaultConfigurationIsVisible = 0;
|
|
defaultConfigurationName = Release;
|
|
};
|
|
AD1FB003D80641D59E37D6A0 /* Build configuration list for PBXProject "Flights" */ = {
|
|
isa = XCConfigurationList;
|
|
buildConfigurations = (
|
|
CE9F5DD65F2043CB9B39FC35 /* Debug */,
|
|
586CEED6298F48F5A36032EC /* Release */,
|
|
);
|
|
defaultConfigurationIsVisible = 0;
|
|
defaultConfigurationName = Release;
|
|
};
|
|
T1000000000000000000007A /* Build configuration list for PBXNativeTarget "FlightsTests" */ = {
|
|
isa = XCConfigurationList;
|
|
buildConfigurations = (
|
|
T100000000000000000000BA /* Debug */,
|
|
T100000000000000000000CA /* Release */,
|
|
);
|
|
defaultConfigurationIsVisible = 0;
|
|
defaultConfigurationName = Release;
|
|
};
|
|
/* End XCConfigurationList section */
|
|
};
|
|
rootObject = 5418BEEAEFF644ADA7240CEA /* Project object */;
|
|
}
|