diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2023-08-23 16:23:39 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2023-08-23 16:23:39 +0200 |
| commit | 4f1531bd941bd57ff8452702718a9c34bc14bb74 (patch) | |
| tree | 7571097b9e87649ffd8f53a4945fb7d0b376a35a | |
| parent | b918c2c6b4dd40c3b26da5b0f898da1cbf416497 (diff) | |
| parent | 5fec677f4877320566a610cb9e04e0b4f9d3598b (diff) | |
| download | mullvadvpn-4f1531bd941bd57ff8452702718a9c34bc14bb74.tar.xz mullvadvpn-4f1531bd941bd57ff8452702718a9c34bc14bb74.zip | |
Merge branch 'add-tests-for-app-router-ios-280'
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 561 | ||||
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPN.xcscheme | 11 | ||||
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNTests.xcscheme | 11 | ||||
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/Routing.xcscheme | 66 | ||||
| -rw-r--r-- | ios/MullvadVPN/Classes/AppRoutes.swift (renamed from ios/MullvadVPN/Routing/AppRoutes.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Containers/Root/RootContainerViewController.swift | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/AccountCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/AccountCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/AccountDeletionCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/AccountDeletionCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/AccountRedeemingVoucherCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/AccountRedeemingVoucherCoordinator.swift) | 5 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/AddCreditSucceededCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/AddCreditSucceededCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/ApplicationCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/ChangeLogCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/InAppPurchaseCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/InAppPurchaseCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/LoginCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/LoginCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/OutOfTimeCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/RevokedCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/RevokedCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/SafariCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/SafariCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/SelectLocationCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/SettingsCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/SettingsCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/SettingsRedeemVoucherCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/SettingsRedeemVoucherCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/SetupAccountCompletedCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/SetupAccountCompletedCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/TermsOfServiceCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/TermsOfServiceCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/TunnelCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/TunnelCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift (renamed from ios/MullvadVPN/Coordinators/App/WelcomeCoordinator.swift) | 1 | ||||
| -rw-r--r-- | ios/MullvadVPN/View controllers/Settings/SettingsViewController.swift | 1 | ||||
| -rw-r--r-- | ios/Routing/Coordinator.swift (renamed from ios/MullvadVPN/Coordinators/Base/Coordinator.swift) | 22 | ||||
| -rw-r--r-- | ios/Routing/ModalPresentationConfiguration.swift (renamed from ios/MullvadVPN/Coordinators/Base/ModalPresentationConfiguration.swift) | 22 | ||||
| -rw-r--r-- | ios/Routing/PresentationControllerDismissalInterceptor.swift (renamed from ios/MullvadVPN/Coordinators/Base/PresentationControllerDismissalInterceptor.swift) | 0 | ||||
| -rw-r--r-- | ios/Routing/Router/AppRouteProtocol.swift (renamed from ios/MullvadVPN/Routing/AppRouteProtocol.swift) | 6 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouter.swift (renamed from ios/MullvadVPN/Routing/ApplicationRouter.swift) | 20 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterDelegate.swift (renamed from ios/MullvadVPN/Routing/ApplicationRouterDelegate.swift) | 2 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterTypes.swift (renamed from ios/MullvadVPN/Routing/ApplicationRouterTypes.swift) | 22 | ||||
| -rw-r--r-- | ios/Routing/Routing.h | 19 | ||||
| -rw-r--r-- | ios/RoutingTests/RouterBlockDelegate.swift | 54 | ||||
| -rw-r--r-- | ios/RoutingTests/RoutingTests.swift | 155 | ||||
| -rw-r--r-- | ios/TestPlans/MullvadVPNApp.xctestplan | 7 | ||||
| -rw-r--r-- | ios/TestPlans/MullvadVPNCI.xctestplan | 8 |
37 files changed, 857 insertions, 154 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 0e9d791882..0726d2b1b1 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -53,10 +53,6 @@ 068CE5782927BE4800A068BB /* Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068CE5732927B7A400A068BB /* Migration.swift */; }; 0697D6E728F01513007A9E99 /* TransportMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0697D6E628F01513007A9E99 /* TransportMonitor.swift */; }; 06AC116228F94C450037AF9A /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; }; - 5802EBC52A8E44AC00E5CE4C /* AppRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */; }; - 5802EBC72A8E457A00E5CE4C /* AppRouteProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC62A8E457A00E5CE4C /* AppRouteProtocol.swift */; }; - 5802EBC92A8E45BA00E5CE4C /* ApplicationRouterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC82A8E45BA00E5CE4C /* ApplicationRouterDelegate.swift */; }; - 5802EBCB2A8E45DC00E5CE4C /* ApplicationRouterTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBCA2A8E45DC00E5CE4C /* ApplicationRouterTypes.swift */; }; 5803B4B02940A47300C23744 /* TunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5803B4AF2940A47300C23744 /* TunnelConfiguration.swift */; }; 5803B4B22940A48700C23744 /* TunnelStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5803B4B12940A48700C23744 /* TunnelStore.swift */; }; 5806767C27048E9B00C858CB /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E7B224146470008646E /* PacketTunnelProvider.swift */; }; @@ -97,10 +93,7 @@ 5835B7CC233B76CB0096D79F /* TunnelManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5835B7CB233B76CB0096D79F /* TunnelManager.swift */; }; 583D86482A2678DC0060D63B /* DeviceStateAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583D86472A2678DC0060D63B /* DeviceStateAccessor.swift */; }; 583DA21425FA4B5C00318683 /* LocationDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583DA21325FA4B5C00318683 /* LocationDataSource.swift */; }; - 583FE00C29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE00B29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift */; }; - 583FE00E29C0D586006E85F9 /* OutOfTimeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE00D29C0D586006E85F9 /* OutOfTimeCoordinator.swift */; }; 583FE01029C0F532006E85F9 /* CustomSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE00F29C0F532006E85F9 /* CustomSplitViewController.swift */; }; - 583FE01229C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE01129C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift */; }; 583FE02429C1ACB3006E85F9 /* RESTCreateApplePaymentResponse+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FAE67828F83CA50033DD93 /* RESTCreateApplePaymentResponse+Localization.swift */; }; 584023222A406BF5007B27AC /* TunnelObfuscator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584023212A406BF5007B27AC /* TunnelObfuscator.swift */; }; 584023292A407F5F007B27AC /* libtunnel_obfuscator_proxy.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 584023282A407F5F007B27AC /* libtunnel_obfuscator_proxy.a */; }; @@ -111,7 +104,6 @@ 5846227126E229F20035F7C2 /* StoreSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227026E229F20035F7C2 /* StoreSubscription.swift */; }; 5846227326E22A160035F7C2 /* StorePaymentObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227226E22A160035F7C2 /* StorePaymentObserver.swift */; }; 5846227726E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5846227626E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift */; }; - 5847D58D29B7740F008C3808 /* RevokedCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5847D58C29B7740F008C3808 /* RevokedCoordinator.swift */; }; 584D26C4270C855B004EA533 /* PreferencesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584D26C3270C855A004EA533 /* PreferencesDataSource.swift */; }; 584D26C6270C8741004EA533 /* SettingsDNSTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584D26C5270C8741004EA533 /* SettingsDNSTextCell.swift */; }; 584EBDBD2747C98F00A0C9FD /* NSAttributedString+Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584EBDBC2747C98F00A0C9FD /* NSAttributedString+Markdown.swift */; }; @@ -137,7 +129,6 @@ 5867771429097BCD006F721F /* PaymentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867771329097BCD006F721F /* PaymentState.swift */; }; 5867771629097C5B006F721F /* ProductState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867771529097C5B006F721F /* ProductState.swift */; }; 5868585524054096000B8131 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5868585424054096000B8131 /* AppButton.swift */; }; - 586891CD29D452E4002A8278 /* SafariCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586891CC29D452E4002A8278 /* SafariCoordinator.swift */; }; 58695AA02A4ADA9200328DB3 /* TunnelObfuscationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58695A9F2A4ADA9200328DB3 /* TunnelObfuscationTests.swift */; }; 58695AA72A4B109F00328DB3 /* TunnelObfuscation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5840231F2A406BF5007B27AC /* TunnelObfuscation.framework */; }; 586A0DCB2A20E359006C731C /* MullvadTypes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58D223D5294C8E5E0029F5F8 /* MullvadTypes.framework */; }; @@ -165,7 +156,6 @@ 5878A27B2909649A0096FC88 /* CustomOverlayRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878A27A2909649A0096FC88 /* CustomOverlayRenderer.swift */; }; 5878A27D2909657C0096FC88 /* RevokedDeviceInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878A27C2909657C0096FC88 /* RevokedDeviceInteractor.swift */; }; 5878F50029CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878F4FF29CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift */; }; - 5878F50229CDB989003D4BE2 /* ChangeLogCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878F50129CDB989003D4BE2 /* ChangeLogCoordinator.swift */; }; 587988C728A2A01F00E3DF54 /* AccountDataThrottling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */; }; 587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */; }; 587AD7C623421D7000E93A53 /* TunnelSettingsV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587AD7C523421D7000E93A53 /* TunnelSettingsV1.swift */; }; @@ -175,8 +165,6 @@ 587B753D2666468F00DEF7E9 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753C2666468F00DEF7E9 /* NotificationController.swift */; }; 587B753F2668E5A700DEF7E9 /* NotificationContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753E2668E5A700DEF7E9 /* NotificationContainerView.swift */; }; 587B75412668FD7800DEF7E9 /* AccountExpirySystemNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B75402668FD7700DEF7E9 /* AccountExpirySystemNotificationProvider.swift */; }; - 587C92FE2986E28100FB9664 /* SelectLocationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587C92FD2986E28100FB9664 /* SelectLocationCoordinator.swift */; }; - 587C93002986E2B600FB9664 /* TermsOfServiceCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587C92FF2986E2B600FB9664 /* TermsOfServiceCoordinator.swift */; }; 587CBFE322807F530028DED3 /* UIColor+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */; }; 587D96742886D87C00CD8F1C /* DeviceManagementContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587D96732886D87C00CD8F1C /* DeviceManagementContentView.swift */; }; 587D9676288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587D9675288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift */; }; @@ -205,7 +193,6 @@ 5893716A28817A45004EE76C /* DeviceManagementViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5893716928817A45004EE76C /* DeviceManagementViewController.swift */; }; 5893C6F929C1B480009090D1 /* DNSSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8528197958002E0998 /* DNSSettings.swift */; }; 5893C6FA29C1B481009090D1 /* DNSSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580F8B8528197958002E0998 /* DNSSettings.swift */; }; - 5893C6FC29C311E9009090D1 /* ApplicationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5893C6FB29C311E9009090D1 /* ApplicationRouter.swift */; }; 58968FAE28743E2000B799DC /* TunnelInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58968FAD28743E2000B799DC /* TunnelInteractor.swift */; }; 5896AE84246D5889005B36CB /* CustomDateComponentsFormatting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5896AE83246D5889005B36CB /* CustomDateComponentsFormatting.swift */; }; 5896AE86246D6AD8005B36CB /* CustomDateComponentsFormattingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5896AE85246D6AD8005B36CB /* CustomDateComponentsFormattingTests.swift */; }; @@ -217,7 +204,7 @@ 5898D29229017CA000EB5EBA /* ProxyURLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063687AF28EB083800BE7161 /* ProxyURLRequest.swift */; }; 5898D29F29017DD000EB5EBA /* RelaySelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CD422AFBA39009B9D8E /* RelaySelector.swift */; }; 5898D2A129017EF400EB5EBA /* libRelaySelector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D29829017DAC00EB5EBA /* libRelaySelector.a */; }; - 5898D2A22901801000EB5EBA /* MullvadREST.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06799ABC28F98E1D00ACD94E /* MullvadREST.framework */; }; + 5898D2A22901801000EB5EBA /* MullvadREST.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06799ABC28F98E1D00ACD94E /* MullvadREST.framework */; platformFilter = ios; }; 5898D2A8290182B000EB5EBA /* TunnelProviderReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5898D2A7290182B000EB5EBA /* TunnelProviderReply.swift */; }; 5898D2A92901844E00EB5EBA /* libRelaySelector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D29829017DAC00EB5EBA /* libRelaySelector.a */; }; 5898D2AA2901844E00EB5EBA /* libTunnelProviderMessaging.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D28929017BD400EB5EBA /* libTunnelProviderMessaging.a */; }; @@ -253,19 +240,17 @@ 58B993B12608A34500BA7811 /* LoginContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B993B02608A34500BA7811 /* LoginContentView.swift */; }; 58B9EB152489139B00095626 /* RESTError+Display.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B9EB142489139B00095626 /* RESTError+Display.swift */; }; 58BA693123EADA6A009DC256 /* SimulatorTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BA693023EADA6A009DC256 /* SimulatorTunnelProvider.swift */; }; - 58BBB39729717E0C00C8DB7C /* ApplicationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BBB39629717E0C00C8DB7C /* ApplicationCoordinator.swift */; }; 58BFA5C622A7C97F00A6173D /* RelayCacheTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5C522A7C97F00A6173D /* RelayCacheTracker.swift */; }; 58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; }; 58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */; }; 58C3F4F92964B08300D72515 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3F4F82964B08300D72515 /* MapViewController.swift */; }; - 58C3F4FB296C3AD500D72515 /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3F4FA296C3AD500D72515 /* SettingsCoordinator.swift */; }; 58C3FA662A38549D006A450A /* MockFileCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3FA652A38549D006A450A /* MockFileCache.swift */; }; 58C3FA682A385C89006A450A /* FileCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3FA672A385C89006A450A /* FileCacheTests.swift */; }; 58C76A082A33850E00100D75 /* ApplicationTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C76A072A33850E00100D75 /* ApplicationTarget.swift */; }; 58C76A092A33850E00100D75 /* ApplicationTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C76A072A33850E00100D75 /* ApplicationTarget.swift */; }; 58C76A0B2A338E4300100D75 /* BackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C76A0A2A338E4300100D75 /* BackgroundTask.swift */; }; 58C774BE29A7A249003A1A56 /* CustomNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C774BD29A7A249003A1A56 /* CustomNavigationController.swift */; }; - 58C7A43E2A863F470060C66F /* PacketTunnelCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */; }; + 58C7A43E2A863F470060C66F /* PacketTunnelCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */; platformFilter = ios; }; 58C7A4462A863F490060C66F /* PacketTunnelCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C7A4382A863F450060C66F /* PacketTunnelCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58C7A4492A863F490060C66F /* PacketTunnelCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */; }; 58C7A44A2A863F490060C66F /* PacketTunnelCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -283,8 +268,6 @@ 58C7A46A2A8643A90060C66F /* ICMPHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 58218E1628B65396000C624F /* ICMPHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58C7A4702A8649ED0060C66F /* PingerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C7A46F2A8649ED0060C66F /* PingerTests.swift */; }; 58C8191829FAA2C400DEB1B4 /* NotificationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C8191729FAA2C400DEB1B4 /* NotificationConfiguration.swift */; }; - 58CAF9F82983D36800BE19F7 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAF9F72983D36800BE19F7 /* Coordinator.swift */; }; - 58CAF9FA2983E0C600BE19F7 /* LoginCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAF9F92983E0C600BE19F7 /* LoginCoordinator.swift */; }; 58CAFA002983FF0200BE19F7 /* LoginInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAF9FF2983FF0200BE19F7 /* LoginInteractor.swift */; }; 58CAFA032985367600BE19F7 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAFA01298530DC00BE19F7 /* Promise.swift */; }; 58CC40EF24A601900019D96E /* ObserverList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CC40EE24A601900019D96E /* ObserverList.swift */; }; @@ -384,7 +367,6 @@ 58F0974F2A20C31100DA2DAD /* WireGuardKitTypes in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 58F0974D2A20C31100DA2DAD /* WireGuardKitTypes */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 58F097512A20C35000DA2DAD /* WireGuardKitTypes in Frameworks */ = {isa = PBXBuildFile; productRef = 58F097502A20C35000DA2DAD /* WireGuardKitTypes */; }; 58F097542A20C36000DA2DAD /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 58F097532A20C36000DA2DAD /* WireGuardKit */; }; - 58F185AA298A3E3E00075977 /* TunnelCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F185A9298A3E3E00075977 /* TunnelCoordinator.swift */; }; 58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */; }; 58F2E144276A13F300A79513 /* StartTunnelOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F2E143276A13F300A79513 /* StartTunnelOperation.swift */; }; 58F2E146276A2C9900A79513 /* StopTunnelOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F2E145276A2C9900A79513 /* StopTunnelOperation.swift */; }; @@ -403,6 +385,7 @@ 58FEEB58260B662E00A621A8 /* AutomaticKeyboardResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FEEB57260B662E00A621A8 /* AutomaticKeyboardResponder.swift */; }; 58FF2C03281BDE02009EF542 /* SettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FF2C02281BDE02009EF542 /* SettingsManager.swift */; }; 7A09C98129D99215000C2CAC /* String+FuzzyMatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A09C98029D99215000C2CAC /* String+FuzzyMatch.swift */; }; + 7A11DD0B2A9495D400098CD8 /* AppRoutes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */; }; 7A1A26432A2612AE00B978AA /* PaymentAlertPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1A26422A2612AE00B978AA /* PaymentAlertPresenter.swift */; }; 7A21DACF2A30AA3700A787A9 /* UITextField+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A21DACE2A30AA3700A787A9 /* UITextField+Appearance.swift */; }; 7A42DEC92A05164100B209BE /* SettingsInputCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A42DEC82A05164100B209BE /* SettingsInputCell.swift */; }; @@ -412,9 +395,40 @@ 7A818F1F29F0305800C7F0F4 /* RootConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A818F1E29F0305800C7F0F4 /* RootConfiguration.swift */; }; 7A83C3FF2A55B72E00DFB83A /* MullvadVPNApp.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = 7A83C3FE2A55B72E00DFB83A /* MullvadVPNApp.xctestplan */; }; 7A83C4022A57FAA800DFB83A /* SettingsDNSInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A83C4012A57FAA800DFB83A /* SettingsDNSInfoCell.swift */; }; + 7A88DCD82A8FABBE00D2FF0E /* Routing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */; }; + 7A88DCDF2A8FABBF00D2FF0E /* RoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A88DCDE2A8FABBF00D2FF0E /* RoutingTests.swift */; }; + 7A88DCEC2A8FB08D00D2FF0E /* MullvadLogging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58D223F3294C8FF00029F5F8 /* MullvadLogging.framework */; }; + 7A88DCF12A8FB0B900D2FF0E /* ModalPresentationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE00B29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift */; }; + 7A88DCF22A8FB0B900D2FF0E /* PresentationControllerDismissalInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583FE01129C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift */; }; + 7A88DCF32A93471F00D2FF0E /* ApplicationRouterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC82A8E45BA00E5CE4C /* ApplicationRouterDelegate.swift */; }; + 7A88DCF42A93471F00D2FF0E /* ApplicationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5893C6FB29C311E9009090D1 /* ApplicationRouter.swift */; }; + 7A88DCF52A93471F00D2FF0E /* ApplicationRouterTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBCA2A8E45DC00E5CE4C /* ApplicationRouterTypes.swift */; }; + 7A88DCF62A93471F00D2FF0E /* AppRouteProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5802EBC62A8E457A00E5CE4C /* AppRouteProtocol.swift */; }; + 7A9CCCB32A96302800DD6A34 /* WelcomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA12A96302700DD6A34 /* WelcomeCoordinator.swift */; }; + 7A9CCCB42A96302800DD6A34 /* TermsOfServiceCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA22A96302700DD6A34 /* TermsOfServiceCoordinator.swift */; }; + 7A9CCCB52A96302800DD6A34 /* AddCreditSucceededCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA32A96302700DD6A34 /* AddCreditSucceededCoordinator.swift */; }; + 7A9CCCB62A96302800DD6A34 /* OutOfTimeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA42A96302700DD6A34 /* OutOfTimeCoordinator.swift */; }; + 7A9CCCB72A96302800DD6A34 /* RevokedCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA52A96302700DD6A34 /* RevokedCoordinator.swift */; }; + 7A9CCCB82A96302800DD6A34 /* SetupAccountCompletedCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA62A96302700DD6A34 /* SetupAccountCompletedCoordinator.swift */; }; + 7A9CCCB92A96302800DD6A34 /* SelectLocationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA72A96302700DD6A34 /* SelectLocationCoordinator.swift */; }; + 7A9CCCBA2A96302800DD6A34 /* AccountRedeemingVoucherCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA82A96302700DD6A34 /* AccountRedeemingVoucherCoordinator.swift */; }; + 7A9CCCBB2A96302800DD6A34 /* InAppPurchaseCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCA92A96302700DD6A34 /* InAppPurchaseCoordinator.swift */; }; + 7A9CCCBC2A96302800DD6A34 /* ChangeLogCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAA2A96302700DD6A34 /* ChangeLogCoordinator.swift */; }; + 7A9CCCBD2A96302800DD6A34 /* LoginCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAB2A96302800DD6A34 /* LoginCoordinator.swift */; }; + 7A9CCCBE2A96302800DD6A34 /* AccountDeletionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAC2A96302800DD6A34 /* AccountDeletionCoordinator.swift */; }; + 7A9CCCBF2A96302800DD6A34 /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAD2A96302800DD6A34 /* SettingsCoordinator.swift */; }; + 7A9CCCC02A96302800DD6A34 /* SettingsRedeemVoucherCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAE2A96302800DD6A34 /* SettingsRedeemVoucherCoordinator.swift */; }; + 7A9CCCC12A96302800DD6A34 /* AccountCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCAF2A96302800DD6A34 /* AccountCoordinator.swift */; }; + 7A9CCCC22A96302800DD6A34 /* SafariCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCB02A96302800DD6A34 /* SafariCoordinator.swift */; }; + 7A9CCCC32A96302800DD6A34 /* ApplicationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCB12A96302800DD6A34 /* ApplicationCoordinator.swift */; }; + 7A9CCCC42A96302800DD6A34 /* TunnelCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CCCB22A96302800DD6A34 /* TunnelCoordinator.swift */; }; + 7ABCA5B32A9349F20044A708 /* Routing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */; }; + 7ABCA5B42A9349F20044A708 /* Routing.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7ABCA5B72A9353C60044A708 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAF9F72983D36800BE19F7 /* Coordinator.swift */; }; 7ABE318D2A1CDD4500DF4963 /* UIFont+Weight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ABE318C2A1CDD4500DF4963 /* UIFont+Weight.swift */; }; + 7AE044BB2A935726003915D8 /* Routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A88DCD02A8FABBE00D2FF0E /* Routing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7AE47E522A17972A000418DA /* CustomAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE47E512A17972A000418DA /* CustomAlertViewController.swift */; }; - 7AF0419E29E957EB00D492DD /* AccountCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF0419D29E957EB00D492DD /* AccountCoordinator.swift */; }; + 7AF6E5F02A95051E00F2679D /* RouterBlockDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF6E5EF2A95051E00F2679D /* RouterBlockDelegate.swift */; }; 7AF9BE992A4E0FE900DBFEDB /* MarkdownStylingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE982A4E0FE900DBFEDB /* MarkdownStylingOptions.swift */; }; A917351F29FAA9C400D5DCFD /* RESTTransportStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917351E29FAA9C400D5DCFD /* RESTTransportStrategy.swift */; }; A917352129FAAA5200D5DCFD /* TransportStrategyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917352029FAAA5200D5DCFD /* TransportStrategyTests.swift */; }; @@ -462,28 +476,21 @@ F028A56C2A34D8E600C0CAA3 /* AddCreditSucceededViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028A56B2A34D8E600C0CAA3 /* AddCreditSucceededViewController.swift */; }; F028A56E2A34DCC600C0CAA3 /* RedeemVoucherInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028A56D2A34DCC600C0CAA3 /* RedeemVoucherInteractor.swift */; }; F03580252A13842C00E5DAFD /* IncreasedHitButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F03580242A13842C00E5DAFD /* IncreasedHitButton.swift */; }; - F041CD562A38B0B7001B703B /* SettingsRedeemVoucherCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F041CD552A38B0B7001B703B /* SettingsRedeemVoucherCoordinator.swift */; }; - F0465B5C2A7927B40004089E /* AddCreditSucceededCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0465B5B2A7927B40004089E /* AddCreditSucceededCoordinator.swift */; }; F04FBE612A8379EE009278D7 /* AppPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04FBE602A8379EE009278D7 /* AppPreferences.swift */; }; F07BF2582A26112D00042943 /* InputTextFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07BF2572A26112D00042943 /* InputTextFormatterTests.swift */; }; F07BF2622A26279100042943 /* RedeemVoucherOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07BF2612A26279100042943 /* RedeemVoucherOperation.swift */; }; - F07C0A052A52D4C3009825CA /* AccountRedeemingVoucherCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07C0A042A52D4C3009825CA /* AccountRedeemingVoucherCoordinator.swift */; }; - F07C0A072A52DA64009825CA /* SetupAccountCompletedCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07C0A062A52DA64009825CA /* SetupAccountCompletedCoordinator.swift */; }; F07CFF2029F2720E008C0343 /* RegisteredDeviceInAppNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F07CFF1F29F2720E008C0343 /* RegisteredDeviceInAppNotificationProvider.swift */; }; F0C2AEFD2A0BB5CC00986207 /* NotificationProviderIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C2AEFC2A0BB5CC00986207 /* NotificationProviderIdentifier.swift */; }; F0C6FA812A66E23300F521F0 /* DeleteAccountOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C6FA802A66E23300F521F0 /* DeleteAccountOperation.swift */; }; - F0C6FA832A6A729500F521F0 /* InAppPurchaseCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C6FA822A6A729500F521F0 /* InAppPurchaseCoordinator.swift */; }; F0C6FA852A6A733700F521F0 /* InAppPurchaseInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C6FA842A6A733700F521F0 /* InAppPurchaseInteractor.swift */; }; F0E3618B2A4ADD2F00AEEF2B /* WelcomeContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E3618A2A4ADD2F00AEEF2B /* WelcomeContentView.swift */; }; F0E8CC032A4C753B007ED3B4 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8CC022A4C753B007ED3B4 /* WelcomeViewController.swift */; }; - F0E8CC052A4CC88F007ED3B4 /* WelcomeCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8CC042A4CC88F007ED3B4 /* WelcomeCoordinator.swift */; }; F0E8CC0A2A4EE127007ED3B4 /* SetupAccountCompletedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8CC092A4EE127007ED3B4 /* SetupAccountCompletedContentView.swift */; }; F0E8CC0C2A4EE672007ED3B4 /* SetupAccountCompletedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8CC0B2A4EE672007ED3B4 /* SetupAccountCompletedController.swift */; }; F0E8E4BB2A56C9F100ED26A3 /* WelcomeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4BA2A56C9F100ED26A3 /* WelcomeInteractor.swift */; }; F0E8E4C12A602CCB00ED26A3 /* AccountDeletionContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4C02A602CCB00ED26A3 /* AccountDeletionContentView.swift */; }; F0E8E4C32A602E0D00ED26A3 /* AccountDeletionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4C22A602E0D00ED26A3 /* AccountDeletionViewModel.swift */; }; F0E8E4C52A60499100ED26A3 /* AccountDeletionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4C42A60499100ED26A3 /* AccountDeletionViewController.swift */; }; - F0E8E4C72A604CBE00ED26A3 /* AccountDeletionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4C62A604CBE00ED26A3 /* AccountDeletionCoordinator.swift */; }; F0E8E4C92A604E7400ED26A3 /* AccountDeletionInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E8E4C82A604E7400ED26A3 /* AccountDeletionInteractor.swift */; }; F0EF50D32A8FA47E0031E8DF /* ChangeLogInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EF50D22A8FA47E0031E8DF /* ChangeLogInteractor.swift */; }; F0EF50D52A949F8E0031E8DF /* ChangeLogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EF50D42A949F8E0031E8DF /* ChangeLogViewModel.swift */; }; @@ -742,6 +749,34 @@ remoteGlobalIDString = 06799ABB28F98E1D00ACD94E; remoteInfo = MullvadREST; }; + 7A88DCD92A8FABBE00D2FF0E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7A88DCCD2A8FABBE00D2FF0E; + remoteInfo = Routing; + }; + 7A88DCDB2A8FABBE00D2FF0E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 58CE5E5F224146200008646E; + remoteInfo = MullvadVPN; + }; + 7A88DCEE2A8FB08D00D2FF0E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 58D223F2294C8FF00029F5F8; + remoteInfo = MullvadLogging; + }; + 7ABCA5B52A9349F20044A708 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 58CE5E58224146200008646E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7A88DCCD2A8FABBE00D2FF0E; + remoteInfo = Routing; + }; A97F1F452A1F4E1A00ECEFDE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 58CE5E58224146200008646E /* Project object */; @@ -810,6 +845,7 @@ 58D223E7294C8F120029F5F8 /* MullvadTypes.framework in Embed Frameworks */, 58D223FA294C8FF10029F5F8 /* MullvadLogging.framework in Embed Frameworks */, A9EC20F02A5D79ED0040D56E /* TunnelObfuscation.framework in Embed Frameworks */, + 7ABCA5B42A9349F20044A708 /* Routing.framework in Embed Frameworks */, 06799AD228F98E1D00ACD94E /* MullvadREST.framework in Embed Frameworks */, 58D223CD294C8BCB0029F5F8 /* Operations.framework in Embed Frameworks */, A97F1F482A1F4E1A00ECEFDE /* MullvadTransport.framework in Embed Frameworks */, @@ -888,6 +924,16 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + 7A88DCF02A8FB08D00D2FF0E /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -1001,7 +1047,6 @@ 583DA21325FA4B5C00318683 /* LocationDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationDataSource.swift; sourceTree = "<group>"; }; 583E1E292848DF67004838B3 /* OperationObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationObserverTests.swift; sourceTree = "<group>"; }; 583FE00B29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalPresentationConfiguration.swift; sourceTree = "<group>"; }; - 583FE00D29C0D586006E85F9 /* OutOfTimeCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutOfTimeCoordinator.swift; sourceTree = "<group>"; }; 583FE00F29C0F532006E85F9 /* CustomSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomSplitViewController.swift; sourceTree = "<group>"; }; 583FE01129C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentationControllerDismissalInterceptor.swift; sourceTree = "<group>"; }; 5840231F2A406BF5007B27AC /* TunnelObfuscation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TunnelObfuscation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1019,7 +1064,6 @@ 5846227026E229F20035F7C2 /* StoreSubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreSubscription.swift; sourceTree = "<group>"; }; 5846227226E22A160035F7C2 /* StorePaymentObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentObserver.swift; sourceTree = "<group>"; }; 5846227626E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorePaymentManagerDelegate.swift; sourceTree = "<group>"; }; - 5847D58C29B7740F008C3808 /* RevokedCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevokedCoordinator.swift; sourceTree = "<group>"; }; 584B26F3237434D00073B10E /* RelaySelectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorTests.swift; sourceTree = "<group>"; }; 584D0111299134AB00531822 /* Version.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; }; 584D26BE270C550B004EA533 /* AnyIPAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyIPAddress.swift; sourceTree = "<group>"; }; @@ -1051,7 +1095,6 @@ 5867771329097BCD006F721F /* PaymentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentState.swift; sourceTree = "<group>"; }; 5867771529097C5B006F721F /* ProductState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductState.swift; sourceTree = "<group>"; }; 5868585424054096000B8131 /* AppButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = "<group>"; }; - 586891CC29D452E4002A8278 /* SafariCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariCoordinator.swift; sourceTree = "<group>"; }; 58695A9D2A4ADA9100328DB3 /* TunnelObfuscationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TunnelObfuscationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58695A9F2A4ADA9200328DB3 /* TunnelObfuscationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelObfuscationTests.swift; sourceTree = "<group>"; }; 586A95112901321B007BAF2B /* IPv6Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv6Endpoint.swift; sourceTree = "<group>"; }; @@ -1076,7 +1119,6 @@ 5878A27A2909649A0096FC88 /* CustomOverlayRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomOverlayRenderer.swift; sourceTree = "<group>"; }; 5878A27C2909657C0096FC88 /* RevokedDeviceInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevokedDeviceInteractor.swift; sourceTree = "<group>"; }; 5878F4FF29CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayoutBuilder.swift"; sourceTree = "<group>"; }; - 5878F50129CDB989003D4BE2 /* ChangeLogCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeLogCoordinator.swift; sourceTree = "<group>"; }; 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDataThrottling.swift; sourceTree = "<group>"; }; 58799A352A84FC9F007BE51F /* PingerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PingerProtocol.swift; sourceTree = "<group>"; }; 587A01FB23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorTunnelProviderHost.swift; sourceTree = "<group>"; }; @@ -1088,8 +1130,6 @@ 587B75402668FD7700DEF7E9 /* AccountExpirySystemNotificationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpirySystemNotificationProvider.swift; sourceTree = "<group>"; }; 587B7544266922BF00DEF7E9 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; }; 587C575226D2615F005EF767 /* PacketTunnelOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelOptions.swift; sourceTree = "<group>"; }; - 587C92FD2986E28100FB9664 /* SelectLocationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationCoordinator.swift; sourceTree = "<group>"; }; - 587C92FF2986E2B600FB9664 /* TermsOfServiceCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsOfServiceCoordinator.swift; sourceTree = "<group>"; }; 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Helpers.swift"; sourceTree = "<group>"; }; 587D96732886D87C00CD8F1C /* DeviceManagementContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceManagementContentView.swift; sourceTree = "<group>"; }; 587D9675288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLayoutConstraint+Helpers.swift"; sourceTree = "<group>"; }; @@ -1160,12 +1200,10 @@ 58B9EB122488ED2100095626 /* AlertPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertPresenter.swift; sourceTree = "<group>"; }; 58B9EB142489139B00095626 /* RESTError+Display.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RESTError+Display.swift"; sourceTree = "<group>"; }; 58BA693023EADA6A009DC256 /* SimulatorTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorTunnelProvider.swift; sourceTree = "<group>"; }; - 58BBB39629717E0C00C8DB7C /* ApplicationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationCoordinator.swift; sourceTree = "<group>"; }; 58BFA5C522A7C97F00A6173D /* RelayCacheTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayCacheTracker.swift; sourceTree = "<group>"; }; 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationConfiguration.swift; sourceTree = "<group>"; }; 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInputGroupView.swift; sourceTree = "<group>"; }; 58C3F4F82964B08300D72515 /* MapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = "<group>"; }; - 58C3F4FA296C3AD500D72515 /* SettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = "<group>"; }; 58C3FA652A38549D006A450A /* MockFileCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFileCache.swift; sourceTree = "<group>"; }; 58C3FA672A385C89006A450A /* FileCacheTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCacheTests.swift; sourceTree = "<group>"; }; 58C76A072A33850E00100D75 /* ApplicationTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationTarget.swift; sourceTree = "<group>"; }; @@ -1178,7 +1216,6 @@ 58C7A46F2A8649ED0060C66F /* PingerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PingerTests.swift; sourceTree = "<group>"; }; 58C8191729FAA2C400DEB1B4 /* NotificationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationConfiguration.swift; sourceTree = "<group>"; }; 58CAF9F72983D36800BE19F7 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; }; - 58CAF9F92983E0C600BE19F7 /* LoginCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCoordinator.swift; sourceTree = "<group>"; }; 58CAF9FF2983FF0200BE19F7 /* LoginInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginInteractor.swift; sourceTree = "<group>"; }; 58CAFA01298530DC00BE19F7 /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = "<group>"; }; 58CC40EE24A601900019D96E /* ObserverList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObserverList.swift; sourceTree = "<group>"; }; @@ -1232,7 +1269,6 @@ 58EF580A25D69D7A00AEBA94 /* ProblemReportSubmissionOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProblemReportSubmissionOverlayView.swift; sourceTree = "<group>"; }; 58EF581025D69DB400AEBA94 /* StatusImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusImageView.swift; sourceTree = "<group>"; }; 58F1311427E0B2AB007AC5BC /* Result+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Result+Extensions.swift"; sourceTree = "<group>"; }; - 58F185A9298A3E3E00075977 /* TunnelCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelCoordinator.swift; sourceTree = "<group>"; }; 58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinnerActivityIndicatorView.swift; sourceTree = "<group>"; }; 58F2E143276A13F300A79513 /* StartTunnelOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartTunnelOperation.swift; sourceTree = "<group>"; }; 58F2E145276A2C9900A79513 /* StopTunnelOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StopTunnelOperation.swift; sourceTree = "<group>"; }; @@ -1264,9 +1300,31 @@ 7A83C3FE2A55B72E00DFB83A /* MullvadVPNApp.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MullvadVPNApp.xctestplan; sourceTree = "<group>"; }; 7A83C4002A55B81A00DFB83A /* MullvadVPNCI.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNCI.xctestplan; sourceTree = "<group>"; }; 7A83C4012A57FAA800DFB83A /* SettingsDNSInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDNSInfoCell.swift; sourceTree = "<group>"; }; + 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Routing.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7A88DCD02A8FABBE00D2FF0E /* Routing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Routing.h; sourceTree = "<group>"; }; + 7A88DCD72A8FABBE00D2FF0E /* RoutingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RoutingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 7A88DCDE2A8FABBF00D2FF0E /* RoutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingTests.swift; sourceTree = "<group>"; }; + 7A9CCCA12A96302700DD6A34 /* WelcomeCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA22A96302700DD6A34 /* TermsOfServiceCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TermsOfServiceCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA32A96302700DD6A34 /* AddCreditSucceededCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddCreditSucceededCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA42A96302700DD6A34 /* OutOfTimeCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutOfTimeCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA52A96302700DD6A34 /* RevokedCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RevokedCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA62A96302700DD6A34 /* SetupAccountCompletedCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupAccountCompletedCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA72A96302700DD6A34 /* SelectLocationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectLocationCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA82A96302700DD6A34 /* AccountRedeemingVoucherCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountRedeemingVoucherCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCA92A96302700DD6A34 /* InAppPurchaseCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InAppPurchaseCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAA2A96302700DD6A34 /* ChangeLogCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeLogCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAB2A96302800DD6A34 /* LoginCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAC2A96302800DD6A34 /* AccountDeletionCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountDeletionCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAD2A96302800DD6A34 /* SettingsCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAE2A96302800DD6A34 /* SettingsRedeemVoucherCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsRedeemVoucherCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCAF2A96302800DD6A34 /* AccountCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCB02A96302800DD6A34 /* SafariCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafariCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCB12A96302800DD6A34 /* ApplicationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationCoordinator.swift; sourceTree = "<group>"; }; + 7A9CCCB22A96302800DD6A34 /* TunnelCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelCoordinator.swift; sourceTree = "<group>"; }; 7ABE318C2A1CDD4500DF4963 /* UIFont+Weight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Weight.swift"; sourceTree = "<group>"; }; 7AE47E512A17972A000418DA /* CustomAlertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAlertViewController.swift; sourceTree = "<group>"; }; - 7AF0419D29E957EB00D492DD /* AccountCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCoordinator.swift; sourceTree = "<group>"; }; + 7AF6E5EF2A95051E00F2679D /* RouterBlockDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterBlockDelegate.swift; sourceTree = "<group>"; }; 7AF9BE982A4E0FE900DBFEDB /* MarkdownStylingOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownStylingOptions.swift; sourceTree = "<group>"; }; A917351E29FAA9C400D5DCFD /* RESTTransportStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTTransportStrategy.swift; sourceTree = "<group>"; }; A917352029FAAA5200D5DCFD /* TransportStrategyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransportStrategyTests.swift; sourceTree = "<group>"; }; @@ -1297,13 +1355,10 @@ F028A56B2A34D8E600C0CAA3 /* AddCreditSucceededViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddCreditSucceededViewController.swift; sourceTree = "<group>"; }; F028A56D2A34DCC600C0CAA3 /* RedeemVoucherInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedeemVoucherInteractor.swift; sourceTree = "<group>"; }; F03580242A13842C00E5DAFD /* IncreasedHitButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncreasedHitButton.swift; sourceTree = "<group>"; }; - F041CD552A38B0B7001B703B /* SettingsRedeemVoucherCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRedeemVoucherCoordinator.swift; sourceTree = "<group>"; }; F0465B5B2A7927B40004089E /* AddCreditSucceededCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddCreditSucceededCoordinator.swift; sourceTree = "<group>"; }; F04FBE602A8379EE009278D7 /* AppPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPreferences.swift; sourceTree = "<group>"; }; F07BF2572A26112D00042943 /* InputTextFormatterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextFormatterTests.swift; sourceTree = "<group>"; }; F07BF2612A26279100042943 /* RedeemVoucherOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RedeemVoucherOperation.swift; sourceTree = "<group>"; }; - F07C0A042A52D4C3009825CA /* AccountRedeemingVoucherCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRedeemingVoucherCoordinator.swift; sourceTree = "<group>"; }; - F07C0A062A52DA64009825CA /* SetupAccountCompletedCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupAccountCompletedCoordinator.swift; sourceTree = "<group>"; }; F07CFF1F29F2720E008C0343 /* RegisteredDeviceInAppNotificationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisteredDeviceInAppNotificationProvider.swift; sourceTree = "<group>"; }; F0C2AEFC2A0BB5CC00986207 /* NotificationProviderIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationProviderIdentifier.swift; sourceTree = "<group>"; }; F0C6FA802A66E23300F521F0 /* DeleteAccountOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteAccountOperation.swift; sourceTree = "<group>"; }; @@ -1311,14 +1366,12 @@ F0C6FA842A6A733700F521F0 /* InAppPurchaseInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppPurchaseInteractor.swift; sourceTree = "<group>"; }; F0E3618A2A4ADD2F00AEEF2B /* WelcomeContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeContentView.swift; sourceTree = "<group>"; }; F0E8CC022A4C753B007ED3B4 /* WelcomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = "<group>"; }; - F0E8CC042A4CC88F007ED3B4 /* WelcomeCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeCoordinator.swift; sourceTree = "<group>"; }; F0E8CC092A4EE127007ED3B4 /* SetupAccountCompletedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupAccountCompletedContentView.swift; sourceTree = "<group>"; }; F0E8CC0B2A4EE672007ED3B4 /* SetupAccountCompletedController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupAccountCompletedController.swift; sourceTree = "<group>"; }; F0E8E4BA2A56C9F100ED26A3 /* WelcomeInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeInteractor.swift; sourceTree = "<group>"; }; F0E8E4C02A602CCB00ED26A3 /* AccountDeletionContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDeletionContentView.swift; sourceTree = "<group>"; }; F0E8E4C22A602E0D00ED26A3 /* AccountDeletionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDeletionViewModel.swift; sourceTree = "<group>"; }; F0E8E4C42A60499100ED26A3 /* AccountDeletionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDeletionViewController.swift; sourceTree = "<group>"; }; - F0E8E4C62A604CBE00ED26A3 /* AccountDeletionCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDeletionCoordinator.swift; sourceTree = "<group>"; }; F0E8E4C82A604E7400ED26A3 /* AccountDeletionInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDeletionInteractor.swift; sourceTree = "<group>"; }; F0EF50D22A8FA47E0031E8DF /* ChangeLogInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeLogInteractor.swift; sourceTree = "<group>"; }; F0EF50D42A949F8E0031E8DF /* ChangeLogViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeLogViewModel.swift; sourceTree = "<group>"; }; @@ -1420,6 +1473,7 @@ 58D223F9294C8FF00029F5F8 /* MullvadLogging.framework in Frameworks */, 58D223E6294C8F120029F5F8 /* MullvadTypes.framework in Frameworks */, 5898D2AA2901844E00EB5EBA /* libTunnelProviderMessaging.a in Frameworks */, + 7ABCA5B32A9349F20044A708 /* Routing.framework in Frameworks */, 58D223CC294C8BCB0029F5F8 /* Operations.framework in Frameworks */, 06799AD128F98E1D00ACD94E /* MullvadREST.framework in Frameworks */, 063F02792902B63F001FA09F /* RelayCache.framework in Frameworks */, @@ -1483,6 +1537,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7A88DCCB2A8FABBE00D2FF0E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A88DCEC2A8FB08D00D2FF0E /* MullvadLogging.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7A88DCD42A8FABBE00D2FF0E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A88DCD82A8FABBE00D2FF0E /* Routing.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A97F1F3E2A1F4E1A00ECEFDE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1561,16 +1631,15 @@ path = MullvadREST; sourceTree = "<group>"; }; - 5802EBC32A8E447000E5CE4C /* Routing */ = { + 5802EBC32A8E447000E5CE4C /* Router */ = { isa = PBXGroup; children = ( 5893C6FB29C311E9009090D1 /* ApplicationRouter.swift */, 5802EBC82A8E45BA00E5CE4C /* ApplicationRouterDelegate.swift */, 5802EBCA2A8E45DC00E5CE4C /* ApplicationRouterTypes.swift */, 5802EBC62A8E457A00E5CE4C /* AppRouteProtocol.swift */, - 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */, ); - path = Routing; + path = Router; sourceTree = "<group>"; }; 580F8B88281A79A7002E0998 /* SettingsManager */ = { @@ -1907,6 +1976,7 @@ 587988C628A2A01F00E3DF54 /* AccountDataThrottling.swift */, F04FBE602A8379EE009278D7 /* AppPreferences.swift */, 58FEEB57260B662E00A621A8 /* AutomaticKeyboardResponder.swift */, + 5802EBC42A8E44AC00E5CE4C /* AppRoutes.swift */, 5871FB95254ADE4E0051A0A4 /* ConsolidatedApplicationLog.swift */, 7AE47E512A17972A000418DA /* CustomAlertViewController.swift */, 5896AE83246D5889005B36CB /* CustomDateComponentsFormatting.swift */, @@ -1956,16 +2026,6 @@ path = StorePaymentManager; sourceTree = "<group>"; }; - 5847D58729B75833008C3808 /* Base */ = { - isa = PBXGroup; - children = ( - 58CAF9F72983D36800BE19F7 /* Coordinator.swift */, - 583FE01129C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift */, - 583FE00B29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift */, - ); - path = Base; - sourceTree = "<group>"; - }; 584F991F2902CBDD001F858D /* Frameworks */ = { isa = PBXGroup; children = ( @@ -2047,31 +2107,6 @@ path = DeviceCheck; sourceTree = "<group>"; }; - 589453E0297807DB0015DA3B /* App */ = { - isa = PBXGroup; - children = ( - 7AF0419D29E957EB00D492DD /* AccountCoordinator.swift */, - F0E8E4C62A604CBE00ED26A3 /* AccountDeletionCoordinator.swift */, - F07C0A042A52D4C3009825CA /* AccountRedeemingVoucherCoordinator.swift */, - F0465B5B2A7927B40004089E /* AddCreditSucceededCoordinator.swift */, - 58BBB39629717E0C00C8DB7C /* ApplicationCoordinator.swift */, - 5878F50129CDB989003D4BE2 /* ChangeLogCoordinator.swift */, - F0C6FA822A6A729500F521F0 /* InAppPurchaseCoordinator.swift */, - 58CAF9F92983E0C600BE19F7 /* LoginCoordinator.swift */, - 583FE00D29C0D586006E85F9 /* OutOfTimeCoordinator.swift */, - 5847D58C29B7740F008C3808 /* RevokedCoordinator.swift */, - 586891CC29D452E4002A8278 /* SafariCoordinator.swift */, - 587C92FD2986E28100FB9664 /* SelectLocationCoordinator.swift */, - 58C3F4FA296C3AD500D72515 /* SettingsCoordinator.swift */, - F041CD552A38B0B7001B703B /* SettingsRedeemVoucherCoordinator.swift */, - F07C0A062A52DA64009825CA /* SetupAccountCompletedCoordinator.swift */, - 587C92FF2986E2B600FB9664 /* TermsOfServiceCoordinator.swift */, - 58F185A9298A3E3E00075977 /* TunnelCoordinator.swift */, - F0E8CC042A4CC88F007ED3B4 /* WelcomeCoordinator.swift */, - ); - path = App; - sourceTree = "<group>"; - }; 5898D28A29017BD400EB5EBA /* TunnelProviderMessaging */ = { isa = PBXGroup; children = ( @@ -2217,8 +2252,24 @@ 58CAF9F22983D32200BE19F7 /* Coordinators */ = { isa = PBXGroup; children = ( - 5847D58729B75833008C3808 /* Base */, - 589453E0297807DB0015DA3B /* App */, + 7A9CCCAF2A96302800DD6A34 /* AccountCoordinator.swift */, + 7A9CCCAC2A96302800DD6A34 /* AccountDeletionCoordinator.swift */, + 7A9CCCA82A96302700DD6A34 /* AccountRedeemingVoucherCoordinator.swift */, + 7A9CCCA32A96302700DD6A34 /* AddCreditSucceededCoordinator.swift */, + 7A9CCCB12A96302800DD6A34 /* ApplicationCoordinator.swift */, + 7A9CCCAA2A96302700DD6A34 /* ChangeLogCoordinator.swift */, + 7A9CCCA92A96302700DD6A34 /* InAppPurchaseCoordinator.swift */, + 7A9CCCAB2A96302800DD6A34 /* LoginCoordinator.swift */, + 7A9CCCA42A96302700DD6A34 /* OutOfTimeCoordinator.swift */, + 7A9CCCA52A96302700DD6A34 /* RevokedCoordinator.swift */, + 7A9CCCB02A96302800DD6A34 /* SafariCoordinator.swift */, + 7A9CCCA72A96302700DD6A34 /* SelectLocationCoordinator.swift */, + 7A9CCCAD2A96302800DD6A34 /* SettingsCoordinator.swift */, + 7A9CCCAE2A96302800DD6A34 /* SettingsRedeemVoucherCoordinator.swift */, + 7A9CCCA62A96302700DD6A34 /* SetupAccountCompletedCoordinator.swift */, + 7A9CCCA22A96302700DD6A34 /* TermsOfServiceCoordinator.swift */, + 7A9CCCB22A96302800DD6A34 /* TunnelCoordinator.swift */, + 7A9CCCA12A96302700DD6A34 /* WelcomeCoordinator.swift */, ); path = Coordinators; sourceTree = "<group>"; @@ -2249,6 +2300,8 @@ 7A83C3FC2A55B39500DFB83A /* TestPlans */, 58C7A4372A863F450060C66F /* PacketTunnelCore */, 58C7A4432A863F490060C66F /* PacketTunnelCoreTests */, + 7A88DCCF2A8FABBE00D2FF0E /* Routing */, + 7A88DCDD2A8FABBE00D2FF0E /* RoutingTests */, 58CE5E61224146200008646E /* Products */, 584F991F2902CBDD001F858D /* Frameworks */, F0EF50D02A8FA2C00031E8DF /* Recovered References */, @@ -2276,6 +2329,8 @@ 58695A9D2A4ADA9100328DB3 /* TunnelObfuscationTests.xctest */, 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */, 58C7A43D2A863F460060C66F /* PacketTunnelCoreTests.xctest */, + 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */, + 7A88DCD72A8FABBE00D2FF0E /* RoutingTests.xctest */, ); name = Products; sourceTree = "<group>"; @@ -2288,7 +2343,6 @@ 58C76A0A2A338E4300100D75 /* BackgroundTask.swift */, 583FE02829C1B079006E85F9 /* Classes */, 58C774C929AB543C003A1A56 /* Containers */, - 5802EBC32A8E447000E5CE4C /* Routing */, 58CAF9F22983D32200BE19F7 /* Coordinators */, 583FE02329C1AC9F006E85F9 /* Extensions */, A9D96B182A82479700A5C673 /* MigrationManager */, @@ -2460,6 +2514,27 @@ path = TestPlans; sourceTree = "<group>"; }; + 7A88DCCF2A8FABBE00D2FF0E /* Routing */ = { + isa = PBXGroup; + children = ( + 5802EBC32A8E447000E5CE4C /* Router */, + 7A88DCD02A8FABBE00D2FF0E /* Routing.h */, + 58CAF9F72983D36800BE19F7 /* Coordinator.swift */, + 583FE00B29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift */, + 583FE01129C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift */, + ); + path = Routing; + sourceTree = "<group>"; + }; + 7A88DCDD2A8FABBE00D2FF0E /* RoutingTests */ = { + isa = PBXGroup; + children = ( + 7A88DCDE2A8FABBF00D2FF0E /* RoutingTests.swift */, + 7AF6E5EF2A95051E00F2679D /* RouterBlockDelegate.swift */, + ); + path = RoutingTests; + sourceTree = "<group>"; + }; A97F1F422A1F4E1A00ECEFDE /* MullvadTransport */ = { isa = PBXGroup; children = ( @@ -2538,6 +2613,8 @@ F0EF50D02A8FA2C00031E8DF /* Recovered References */ = { isa = PBXGroup; children = ( + F0C6FA822A6A729500F521F0 /* InAppPurchaseCoordinator.swift */, + F0465B5B2A7927B40004089E /* AddCreditSucceededCoordinator.swift */, ); name = "Recovered References"; sourceTree = "<group>"; @@ -2613,6 +2690,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7A88DCC92A8FABBE00D2FF0E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AE044BB2A935726003915D8 /* Routing.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A97F1F3C2A1F4E1A00ECEFDE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -2868,6 +2953,7 @@ A97F1F462A1F4E1A00ECEFDE /* PBXTargetDependency */, A9EC20F22A5D79ED0040D56E /* PBXTargetDependency */, 58C7A4482A863F490060C66F /* PBXTargetDependency */, + 7ABCA5B62A9349F20044A708 /* PBXTargetDependency */, ); name = MullvadVPN; packageProductDependencies = ( @@ -3008,6 +3094,45 @@ productReference = 58FBFBE6291622580020E046 /* MullvadRESTTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 7A88DCCD2A8FABBE00D2FF0E /* Routing */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7A88DCE52A8FABBF00D2FF0E /* Build configuration list for PBXNativeTarget "Routing" */; + buildPhases = ( + 7A88DCC92A8FABBE00D2FF0E /* Headers */, + 7A88DCCA2A8FABBE00D2FF0E /* Sources */, + 7A88DCCB2A8FABBE00D2FF0E /* Frameworks */, + 7A88DCCC2A8FABBE00D2FF0E /* Resources */, + 7A88DCF02A8FB08D00D2FF0E /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7A88DCEF2A8FB08D00D2FF0E /* PBXTargetDependency */, + ); + name = Routing; + productName = Routing; + productReference = 7A88DCCE2A8FABBE00D2FF0E /* Routing.framework */; + productType = "com.apple.product-type.framework"; + }; + 7A88DCD62A8FABBE00D2FF0E /* RoutingTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7A88DCE82A8FABBF00D2FF0E /* Build configuration list for PBXNativeTarget "RoutingTests" */; + buildPhases = ( + 7A88DCD32A8FABBE00D2FF0E /* Sources */, + 7A88DCD42A8FABBE00D2FF0E /* Frameworks */, + 7A88DCD52A8FABBE00D2FF0E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7A88DCDA2A8FABBE00D2FF0E /* PBXTargetDependency */, + 7A88DCDC2A8FABBE00D2FF0E /* PBXTargetDependency */, + ); + name = RoutingTests; + productName = RoutingTests; + productReference = 7A88DCD72A8FABBE00D2FF0E /* RoutingTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; A97F1F402A1F4E1A00ECEFDE /* MullvadTransport */ = { isa = PBXNativeTarget; buildConfigurationList = A97F1F4B2A1F4E1A00ECEFDE /* Build configuration list for PBXNativeTarget "MullvadTransport" */; @@ -3111,6 +3236,12 @@ 58FBFBE5291622580020E046 = { CreatedOnToolsVersion = 14.1; }; + 7A88DCCD2A8FABBE00D2FF0E = { + CreatedOnToolsVersion = 14.3.1; + }; + 7A88DCD62A8FABBE00D2FF0E = { + CreatedOnToolsVersion = 14.3.1; + }; A97F1F402A1F4E1A00ECEFDE = { CreatedOnToolsVersion = 14.3; }; @@ -3152,6 +3283,8 @@ 58695A9C2A4ADA9100328DB3 /* TunnelObfuscationTests */, 58C7A4352A863F440060C66F /* PacketTunnelCore */, 58C7A43C2A863F450060C66F /* PacketTunnelCoreTests */, + 7A88DCCD2A8FABBE00D2FF0E /* Routing */, + 7A88DCD62A8FABBE00D2FF0E /* RoutingTests */, ); }; /* End PBXProject section */ @@ -3263,6 +3396,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7A88DCCC2A8FABBE00D2FF0E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7A88DCD52A8FABBE00D2FF0E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; A97F1F3F2A1F4E1A00ECEFDE /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -3490,25 +3637,26 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7A9CCCC42A96302800DD6A34 /* TunnelCoordinator.swift in Sources */, 58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */, 5891BF5125E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift in Sources */, 58E511E628DDDEAC00B0BCDE /* CodingErrors+CustomErrorDescription.swift in Sources */, 58C76A0B2A338E4300100D75 /* BackgroundTask.swift in Sources */, 5864859B29A0EAF2006C5743 /* SecondaryContextPresentationController.swift in Sources */, + 7A9CCCC32A96302800DD6A34 /* ApplicationCoordinator.swift in Sources */, 5864AF0729C78843005B0CD9 /* SettingsCellFactory.swift in Sources */, 587B75412668FD7800DEF7E9 /* AccountExpirySystemNotificationProvider.swift in Sources */, 587988C728A2A01F00E3DF54 /* AccountDataThrottling.swift in Sources */, F04FBE612A8379EE009278D7 /* AppPreferences.swift in Sources */, 5896CEF226972DEB00B0FAE8 /* AccountContentView.swift in Sources */, - 7AF0419E29E957EB00D492DD /* AccountCoordinator.swift in Sources */, 5867771429097BCD006F721F /* PaymentState.swift in Sources */, F0EF50D32A8FA47E0031E8DF /* ChangeLogInteractor.swift in Sources */, F0C2AEFD2A0BB5CC00986207 /* NotificationProviderIdentifier.swift in Sources */, + 7A9CCCB72A96302800DD6A34 /* RevokedCoordinator.swift in Sources */, 587D96742886D87C00CD8F1C /* DeviceManagementContentView.swift in Sources */, - 58C3F4FB296C3AD500D72515 /* SettingsCoordinator.swift in Sources */, + 7A11DD0B2A9495D400098CD8 /* AppRoutes.swift in Sources */, 5846227126E229F20035F7C2 /* StoreSubscription.swift in Sources */, 58421030282D8A3C00F24E46 /* UpdateAccountDataOperation.swift in Sources */, - F0E8CC052A4CC88F007ED3B4 /* WelcomeCoordinator.swift in Sources */, F0E8E4C92A604E7400ED26A3 /* AccountDeletionInteractor.swift in Sources */, 58FF2C03281BDE02009EF542 /* SettingsManager.swift in Sources */, 5803B4B02940A47300C23744 /* TunnelConfiguration.swift in Sources */, @@ -3519,29 +3667,27 @@ 584D26C6270C8741004EA533 /* SettingsDNSTextCell.swift in Sources */, 58F2E148276A307400A79513 /* MapConnectionStatusOperation.swift in Sources */, 58BA693123EADA6A009DC256 /* SimulatorTunnelProvider.swift in Sources */, + 7A9CCCB32A96302800DD6A34 /* WelcomeCoordinator.swift in Sources */, 587B753B2666467500DEF7E9 /* NotificationBannerView.swift in Sources */, 58B993B12608A34500BA7811 /* LoginContentView.swift in Sources */, - F041CD562A38B0B7001B703B /* SettingsRedeemVoucherCoordinator.swift in Sources */, 5878A27529093A310096FC88 /* StorePaymentEvent.swift in Sources */, 7A7AD28D29DC677800480EF1 /* FirstTimeLaunch.swift in Sources */, 58B26E2A2943545A00D5980C /* NotificationManagerDelegate.swift in Sources */, 58A1AA8C23F5584C009F7EA6 /* ConnectionPanelView.swift in Sources */, 5878A27B2909649A0096FC88 /* CustomOverlayRenderer.swift in Sources */, - 5847D58D29B7740F008C3808 /* RevokedCoordinator.swift in Sources */, 588527B2276B3F0700BAA373 /* LoadTunnelConfigurationOperation.swift in Sources */, 7AF9BE992A4E0FE900DBFEDB /* MarkdownStylingOptions.swift in Sources */, 5867770E29096984006F721F /* OutOfTimeInteractor.swift in Sources */, - 58F185AA298A3E3E00075977 /* TunnelCoordinator.swift in Sources */, F03580252A13842C00E5DAFD /* IncreasedHitButton.swift in Sources */, 58F8AC0E25D3F8CE002BE0ED /* ProblemReportReviewViewController.swift in Sources */, F028A56E2A34DCC600C0CAA3 /* RedeemVoucherInteractor.swift in Sources */, 5878A27129091CF20096FC88 /* AccountInteractor.swift in Sources */, 068CE5742927B7A400A068BB /* Migration.swift in Sources */, A92ECC282A7802AB0052F1B1 /* StoredDeviceData.swift in Sources */, - 5802EBC92A8E45BA00E5CE4C /* ApplicationRouterDelegate.swift in Sources */, 58CCA010224249A1004F3011 /* TunnelViewController.swift in Sources */, 58B26E22294351EA00D5980C /* InAppNotificationProvider.swift in Sources */, 5893716A28817A45004EE76C /* DeviceManagementViewController.swift in Sources */, + 7A9CCCB82A96302800DD6A34 /* SetupAccountCompletedCoordinator.swift in Sources */, 58435AC229CB2A350099C71B /* LocationCellFactory.swift in Sources */, 58BFA5C622A7C97F00A6173D /* RelayCacheTracker.swift in Sources */, E158B360285381C60002F069 /* String+AccountFormatting.swift in Sources */, @@ -3553,28 +3699,30 @@ E1FD0DF528AA7CE400299DB4 /* StatusActivityView.swift in Sources */, 0697D6E728F01513007A9E99 /* TransportMonitor.swift in Sources */, 58968FAE28743E2000B799DC /* TunnelInteractor.swift in Sources */, - 587C93002986E2B600FB9664 /* TermsOfServiceCoordinator.swift in Sources */, 5864AF0929C78850005B0CD9 /* PreferencesCellFactory.swift in Sources */, 587B7536266528A200DEF7E9 /* NotificationManager.swift in Sources */, 5820EDA9288FE064006BF4E4 /* DeviceManagementInteractor.swift in Sources */, + 7A9CCCB92A96302800DD6A34 /* SelectLocationCoordinator.swift in Sources */, 58FB865A26EA214400F188BC /* RelayCacheTrackerObserver.swift in Sources */, 58ACF64D26567A5000ACE4B7 /* CustomSwitch.swift in Sources */, 58F2E14C276A61C000A79513 /* RotateKeyOperation.swift in Sources */, 5871FB96254ADE4E0051A0A4 /* ConsolidatedApplicationLog.swift in Sources */, F0E8E4C52A60499100ED26A3 /* AccountDeletionViewController.swift in Sources */, + 7A9CCCC12A96302800DD6A34 /* AccountCoordinator.swift in Sources */, F028A54B2A3370FA00C0CAA3 /* RedeemVoucherContentView.swift in Sources */, 58FEEB58260B662E00A621A8 /* AutomaticKeyboardResponder.swift in Sources */, 5846227326E22A160035F7C2 /* StorePaymentObserver.swift in Sources */, F0E3618B2A4ADD2F00AEEF2B /* WelcomeContentView.swift in Sources */, 58F2E146276A2C9900A79513 /* StopTunnelOperation.swift in Sources */, E1187ABC289BBB850024E748 /* OutOfTimeViewController.swift in Sources */, - 58CAF9FA2983E0C600BE19F7 /* LoginCoordinator.swift in Sources */, - F07C0A072A52DA64009825CA /* SetupAccountCompletedCoordinator.swift in Sources */, + 7A9CCCBD2A96302800DD6A34 /* LoginCoordinator.swift in Sources */, 58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */, 58138E61294871C600684F0C /* DeviceDataThrottling.swift in Sources */, 5878A279290954790096FC88 /* TunnelViewControllerInteractor.swift in Sources */, 7A818F1F29F0305800C7F0F4 /* RootConfiguration.swift in Sources */, + 7A9CCCBF2A96302800DD6A34 /* SettingsCoordinator.swift in Sources */, 582AE3102440A6CA00E6733A /* InputTextFormatter.swift in Sources */, + 7A9CCCBA2A96302800DD6A34 /* AccountRedeemingVoucherCoordinator.swift in Sources */, 5820EDAB288FF0D2006BF4E4 /* DeviceRowView.swift in Sources */, F0E8CC0C2A4EE672007ED3B4 /* SetupAccountCompletedController.swift in Sources */, 5846227726E22A7C0035F7C2 /* StorePaymentManagerDelegate.swift in Sources */, @@ -3584,31 +3732,30 @@ A92ECC242A7802520052F1B1 /* StoredAccountData.swift in Sources */, 5823FA5426CE49F700283BF8 /* TunnelObserver.swift in Sources */, 5888AD87227B17950051EB06 /* SelectLocationViewController.swift in Sources */, - 583FE00C29C0C7FD006E85F9 /* ModalPresentationConfiguration.swift in Sources */, 58293FB3251241B4005D0BB5 /* CustomTextView.swift in Sources */, 586A950E290125F3007BAF2B /* ProductsRequestOperation.swift in Sources */, 5893C6F929C1B480009090D1 /* DNSSettings.swift in Sources */, 58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */, 5864859929A0D028006C5743 /* FormsheetPresentationController.swift in Sources */, + 7A9CCCB52A96302800DD6A34 /* AddCreditSucceededCoordinator.swift in Sources */, 58A99ED3240014A0006599E9 /* TermsOfServiceViewController.swift in Sources */, 58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */, 587CBFE322807F530028DED3 /* UIColor+Helpers.swift in Sources */, + 7A9CCCBE2A96302800DD6A34 /* AccountDeletionCoordinator.swift in Sources */, 588527B4276B4F2F00BAA373 /* SetAccountOperation.swift in Sources */, 585CA70F25F8C44600B47C62 /* UIMetrics.swift in Sources */, E1187ABD289BBB850024E748 /* OutOfTimeContentView.swift in Sources */, 58CC40EF24A601900019D96E /* ObserverList.swift in Sources */, 7A1A26432A2612AE00B978AA /* PaymentAlertPresenter.swift in Sources */, + 7A9CCCBB2A96302800DD6A34 /* InAppPurchaseCoordinator.swift in Sources */, 58CCA01822426713004F3011 /* AccountViewController.swift in Sources */, 5871FBA0254C26C00051A0A4 /* NSRegularExpression+IPAddress.swift in Sources */, F0EF50D52A949F8E0031E8DF /* ChangeLogViewModel.swift in Sources */, - F0C6FA832A6A729500F521F0 /* InAppPurchaseCoordinator.swift in Sources */, F0E8E4BB2A56C9F100ED26A3 /* WelcomeInteractor.swift in Sources */, 5878A27729093A4F0096FC88 /* StorePaymentBlockObserver.swift in Sources */, - 5802EBC52A8E44AC00E5CE4C /* AppRoutes.swift in Sources */, - F07C0A052A52D4C3009825CA /* AccountRedeemingVoucherCoordinator.swift in Sources */, 5868585524054096000B8131 /* AppButton.swift in Sources */, - 5893C6FC29C311E9009090D1 /* ApplicationRouter.swift in Sources */, 58E25F812837BBBB002CFB2C /* SceneDelegate.swift in Sources */, + 7A9CCCB42A96302800DD6A34 /* TermsOfServiceCoordinator.swift in Sources */, 5867771629097C5B006F721F /* ProductState.swift in Sources */, 58C76A082A33850E00100D75 /* ApplicationTarget.swift in Sources */, F07BF2622A26279100042943 /* RedeemVoucherOperation.swift in Sources */, @@ -3624,14 +3771,10 @@ 58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */, 5864AF0829C78849005B0CD9 /* CellFactoryProtocol.swift in Sources */, F0C6FA812A66E23300F521F0 /* DeleteAccountOperation.swift in Sources */, - F0E8E4C72A604CBE00ED26A3 /* AccountDeletionCoordinator.swift in Sources */, F07CFF2029F2720E008C0343 /* RegisteredDeviceInAppNotificationProvider.swift in Sources */, 587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */, - 58CAF9F82983D36800BE19F7 /* Coordinator.swift in Sources */, 5819C2172729595500D6EC38 /* SettingsAddDNSEntryCell.swift in Sources */, - 5802EBC72A8E457A00E5CE4C /* AppRouteProtocol.swift in Sources */, 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */, - 5802EBCB2A8E45DC00E5CE4C /* ApplicationRouterTypes.swift in Sources */, 587EB66A270EFACB00123C75 /* CharacterSet+IPAddress.swift in Sources */, 5888AD83227B11080051EB06 /* SelectLocationCell.swift in Sources */, 5891BF1C25E3E3EB006D6FB0 /* Bundle+ProductVersion.swift in Sources */, @@ -3643,7 +3786,6 @@ 5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */, 58B26E242943520C00D5980C /* NotificationProviderProtocol.swift in Sources */, 5877F94E2A0A59AA0052D9E9 /* NotificationResponse.swift in Sources */, - 583FE01229C0F99A006E85F9 /* PresentationControllerDismissalInterceptor.swift in Sources */, 58677712290976FB006F721F /* SettingsInteractor.swift in Sources */, 58CE5E66224146200008646E /* LoginViewController.swift in Sources */, F0C6FA852A6A733700F521F0 /* InAppPurchaseInteractor.swift in Sources */, @@ -3659,13 +3801,11 @@ 06410E07292D108E00AFC18C /* SettingsStore.swift in Sources */, 586A950D290125F0007BAF2B /* PresentAlertOperation.swift in Sources */, 7A7AD28F29DEDB1C00480EF1 /* SettingsHeaderView.swift in Sources */, - 5878F50229CDB989003D4BE2 /* ChangeLogCoordinator.swift in Sources */, 58B93A1326C3F13600A55733 /* TunnelState.swift in Sources */, 58B26E262943522400D5980C /* NotificationProvider.swift in Sources */, 58CE5E64224146200008646E /* AppDelegate.swift in Sources */, 5878A27329091D6D0096FC88 /* TunnelBlockObserver.swift in Sources */, 58E0A98827C8F46300FE6BDD /* Tunnel.swift in Sources */, - 586891CD29D452E4002A8278 /* SafariCoordinator.swift in Sources */, 58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */, 58EE2E3A272FF814003BFF93 /* SettingsDataSource.swift in Sources */, F0E8E4C12A602CCB00ED26A3 /* AccountDeletionContentView.swift in Sources */, @@ -3675,6 +3815,8 @@ 5878A27D2909657C0096FC88 /* RevokedDeviceInteractor.swift in Sources */, F0E8E4C32A602E0D00ED26A3 /* AccountDeletionViewModel.swift in Sources */, 58677710290975E9006F721F /* SettingsInteractorFactory.swift in Sources */, + 7A9CCCC02A96302800DD6A34 /* SettingsRedeemVoucherCoordinator.swift in Sources */, + 7A9CCCBC2A96302800DD6A34 /* ChangeLogCoordinator.swift in Sources */, 58B26E282943527300D5980C /* SystemNotificationProvider.swift in Sources */, 58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */, F0E8CC0A2A4EE127007ED3B4 /* SetupAccountCompletedContentView.swift in Sources */, @@ -3697,30 +3839,28 @@ 5875960A26F371FC00BF6711 /* Tunnel+Messaging.swift in Sources */, 063687BA28EB234F00BE7161 /* PacketTunnelTransport.swift in Sources */, 587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */, - F0465B5C2A7927B40004089E /* AddCreditSucceededCoordinator.swift in Sources */, 5896AE84246D5889005B36CB /* CustomDateComponentsFormatting.swift in Sources */, 5871167F2910035700D41AAC /* PreferencesInteractor.swift in Sources */, + 7A9CCCC22A96302800DD6A34 /* SafariCoordinator.swift in Sources */, 587AD7C623421D7000E93A53 /* TunnelSettingsV1.swift in Sources */, 58E20771274672CA00DE5D77 /* LaunchViewController.swift in Sources */, F0E8CC032A4C753B007ED3B4 /* WelcomeViewController.swift in Sources */, 584D26C4270C855B004EA533 /* PreferencesDataSource.swift in Sources */, + 7A9CCCB62A96302800DD6A34 /* OutOfTimeCoordinator.swift in Sources */, 58FD5BF024238EB300112C88 /* SKProduct+Formatting.swift in Sources */, 58B43C1925F77DB60002C8C3 /* TunnelControlView.swift in Sources */, 5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */, 7A21DACF2A30AA3700A787A9 /* UITextField+Appearance.swift in Sources */, 58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */, 58ACF64B26553C3F00ACE4B7 /* SettingsSwitchCell.swift in Sources */, - 583FE00E29C0D586006E85F9 /* OutOfTimeCoordinator.swift in Sources */, 7A09C98129D99215000C2CAC /* String+FuzzyMatch.swift in Sources */, 58A8EE5E2976DB00009C0F8D /* StorePaymentManagerError+Display.swift in Sources */, 580F8B8328197881002E0998 /* TunnelSettingsV2.swift in Sources */, 58A8EE5A2976BFBB009C0F8D /* SKError+Localized.swift in Sources */, 7A42DEC92A05164100B209BE /* SettingsInputCell.swift in Sources */, - 58BBB39729717E0C00C8DB7C /* ApplicationCoordinator.swift in Sources */, 5803B4B22940A48700C23744 /* TunnelStore.swift in Sources */, 586A950F29012BEE007BAF2B /* AddressCacheTracker.swift in Sources */, 587B753D2666468F00DEF7E9 /* NotificationController.swift in Sources */, - 587C92FE2986E28100FB9664 /* SelectLocationCoordinator.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3851,6 +3991,29 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 7A88DCCA2A8FABBE00D2FF0E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7ABCA5B72A9353C60044A708 /* Coordinator.swift in Sources */, + 7A88DCF12A8FB0B900D2FF0E /* ModalPresentationConfiguration.swift in Sources */, + 7A88DCF52A93471F00D2FF0E /* ApplicationRouterTypes.swift in Sources */, + 7A88DCF42A93471F00D2FF0E /* ApplicationRouter.swift in Sources */, + 7A88DCF22A8FB0B900D2FF0E /* PresentationControllerDismissalInterceptor.swift in Sources */, + 7A88DCF62A93471F00D2FF0E /* AppRouteProtocol.swift in Sources */, + 7A88DCF32A93471F00D2FF0E /* ApplicationRouterDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7A88DCD32A8FABBE00D2FF0E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A88DCDF2A8FABBF00D2FF0E /* RoutingTests.swift in Sources */, + 7AF6E5F02A95051E00F2679D /* RouterBlockDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A97F1F3D2A1F4E1A00ECEFDE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3933,6 +4096,7 @@ }; 58C7A4402A863F470060C66F /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilter = ios; target = 58C7A4352A863F440060C66F /* PacketTunnelCore */; targetProxy = 58C7A43F2A863F470060C66F /* PBXContainerItemProxy */; }; @@ -3949,6 +4113,7 @@ }; 58C7A4722A864B860060C66F /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilter = ios; target = 58CE5E5F224146200008646E /* MullvadVPN */; targetProxy = 58C7A4712A864B860060C66F /* PBXContainerItemProxy */; }; @@ -4057,6 +4222,26 @@ target = 06799ABB28F98E1D00ACD94E /* MullvadREST */; targetProxy = 58FBFBEB291622580020E046 /* PBXContainerItemProxy */; }; + 7A88DCDA2A8FABBE00D2FF0E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7A88DCCD2A8FABBE00D2FF0E /* Routing */; + targetProxy = 7A88DCD92A8FABBE00D2FF0E /* PBXContainerItemProxy */; + }; + 7A88DCDC2A8FABBE00D2FF0E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 58CE5E5F224146200008646E /* MullvadVPN */; + targetProxy = 7A88DCDB2A8FABBE00D2FF0E /* PBXContainerItemProxy */; + }; + 7A88DCEF2A8FB08D00D2FF0E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 58D223F2294C8FF00029F5F8 /* MullvadLogging */; + targetProxy = 7A88DCEE2A8FB08D00D2FF0E /* PBXContainerItemProxy */; + }; + 7ABCA5B62A9349F20044A708 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7A88DCCD2A8FABBE00D2FF0E /* Routing */; + targetProxy = 7ABCA5B52A9349F20044A708 /* PBXContainerItemProxy */; + }; A97F1F462A1F4E1A00ECEFDE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = A97F1F402A1F4E1A00ECEFDE /* MullvadTransport */; @@ -4069,11 +4254,13 @@ }; A9D99B9C2A1F7DF800DE27D3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilter = ios; target = 06799ABB28F98E1D00ACD94E /* MullvadREST */; targetProxy = A9D99B9B2A1F7DF800DE27D3 /* PBXContainerItemProxy */; }; A9D99B9E2A1F7E0300DE27D3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilter = ios; target = A97F1F402A1F4E1A00ECEFDE /* MullvadTransport */; targetProxy = A9D99B9D2A1F7E0300DE27D3 /* PBXContainerItemProxy */; }; @@ -4568,7 +4755,7 @@ PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnelCoreTests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; + SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; @@ -4590,7 +4777,7 @@ PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnelCoreTests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; + SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; @@ -5079,6 +5266,136 @@ }; name = Release; }; + 7A88DCE62A8FABBF00D2FF0E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5808273928487E3E006B77A4 /* Base.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = "$(CLANG_MODULES_ENABLE_VERIFIER_TOOL)"; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Mullvad VPN AB. All rights reserved."; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).Routing"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7A88DCE72A8FABBF00D2FF0E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5808273928487E3E006B77A4 /* Base.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = "$(CLANG_MODULES_ENABLE_VERIFIER_TOOL)"; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Mullvad VPN AB. All rights reserved."; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).Routing"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 7A88DCE92A8FABBF00D2FF0E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5808273928487E3E006B77A4 /* Base.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = CKG9MXH72F; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.RoutingTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7A88DCEA2A8FABBF00D2FF0E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5808273928487E3E006B77A4 /* Base.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = CKG9MXH72F; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.RoutingTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; A97F1F492A1F4E1A00ECEFDE /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5808273928487E3E006B77A4 /* Base.xcconfig */; @@ -5341,6 +5658,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 7A88DCE52A8FABBF00D2FF0E /* Build configuration list for PBXNativeTarget "Routing" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7A88DCE62A8FABBF00D2FF0E /* Debug */, + 7A88DCE72A8FABBF00D2FF0E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7A88DCE82A8FABBF00D2FF0E /* Build configuration list for PBXNativeTarget "RoutingTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7A88DCE92A8FABBF00D2FF0E /* Debug */, + 7A88DCEA2A8FABBF00D2FF0E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; A97F1F4B2A1F4E1A00ECEFDE /* Build configuration list for PBXNativeTarget "MullvadTransport" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPN.xcscheme b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPN.xcscheme index 2757b5fb64..5781a72fb5 100644 --- a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPN.xcscheme +++ b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPN.xcscheme @@ -254,6 +254,17 @@ ReferencedContainer = "container:MullvadVPN.xcodeproj"> </BuildableReference> </TestableReference> + <TestableReference + skipped = "NO" + parallelizable = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "7A88DCD62A8FABBE00D2FF0E" + BuildableName = "RoutingTests.xctest" + BlueprintName = "RoutingTests" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </TestableReference> </Testables> </TestAction> <LaunchAction diff --git a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNTests.xcscheme b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNTests.xcscheme index a5d976ec07..accf771445 100644 --- a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNTests.xcscheme +++ b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/MullvadVPNTests.xcscheme @@ -47,6 +47,17 @@ ReferencedContainer = "container:MullvadVPN.xcodeproj"> </BuildableReference> </TestableReference> + <TestableReference + skipped = "NO" + parallelizable = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "7A88DCD62A8FABBE00D2FF0E" + BuildableName = "RoutingTests.xctest" + BlueprintName = "RoutingTests" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </TestableReference> </Testables> </TestAction> <LaunchAction diff --git a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/Routing.xcscheme b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/Routing.xcscheme new file mode 100644 index 0000000000..f9c1b1aded --- /dev/null +++ b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/Routing.xcscheme @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "1430" + version = "1.7"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "7A88DCCD2A8FABBE00D2FF0E" + BuildableName = "Routing.framework" + BlueprintName = "Routing" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "7A88DCCD2A8FABBE00D2FF0E" + BuildableName = "Routing.framework" + BlueprintName = "Routing" + ReferencedContainer = "container:MullvadVPN.xcodeproj"> + </BuildableReference> + </MacroExpansion> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/ios/MullvadVPN/Routing/AppRoutes.swift b/ios/MullvadVPN/Classes/AppRoutes.swift index 9373c53b3f..a217fe8539 100644 --- a/ios/MullvadVPN/Routing/AppRoutes.swift +++ b/ios/MullvadVPN/Classes/AppRoutes.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit /** diff --git a/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift b/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift index 728b173e40..afb28ce124 100644 --- a/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift +++ b/ios/MullvadVPN/Containers/Root/RootContainerViewController.swift @@ -6,6 +6,7 @@ // Copyright © 2019 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit enum HeaderBarStyle { diff --git a/ios/MullvadVPN/Coordinators/App/AccountCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift index 08e5a0e0b6..a7d6f261e7 100644 --- a/ios/MullvadVPN/Coordinators/App/AccountCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit enum AccountDismissReason: Equatable { diff --git a/ios/MullvadVPN/Coordinators/App/AccountDeletionCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountDeletionCoordinator.swift index 7e0f674d57..e1e2058ca2 100644 --- a/ios/MullvadVPN/Coordinators/App/AccountDeletionCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountDeletionCoordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import UIKit final class AccountDeletionCoordinator: Coordinator, Presentable { diff --git a/ios/MullvadVPN/Coordinators/App/AccountRedeemingVoucherCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountRedeemingVoucherCoordinator.swift index f81c29c421..9998fd2d85 100644 --- a/ios/MullvadVPN/Coordinators/App/AccountRedeemingVoucherCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountRedeemingVoucherCoordinator.swift @@ -7,16 +7,17 @@ // import MullvadREST +import Routing import UIKit -class AccountRedeemingVoucherCoordinator: Coordinator, Presentable { +public class AccountRedeemingVoucherCoordinator: Coordinator, Presentable { private let navigationController: RootContainerViewController private let viewController: RedeemVoucherViewController var didFinish: ((AccountRedeemingVoucherCoordinator) -> Void)? var didCancel: ((AccountRedeemingVoucherCoordinator) -> Void)? - var presentedViewController: UIViewController { + public var presentedViewController: UIViewController { viewController } diff --git a/ios/MullvadVPN/Coordinators/App/AddCreditSucceededCoordinator.swift b/ios/MullvadVPN/Coordinators/AddCreditSucceededCoordinator.swift index 40539338c0..7d7922adfb 100644 --- a/ios/MullvadVPN/Coordinators/App/AddCreditSucceededCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AddCreditSucceededCoordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import UIKit final class AddCreditSucceededCoordinator: Coordinator { diff --git a/ios/MullvadVPN/Coordinators/App/ApplicationCoordinator.swift b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift index ce28210be9..1ccbb32632 100644 --- a/ios/MullvadVPN/Coordinators/App/ApplicationCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift @@ -9,6 +9,7 @@ import MullvadREST import MullvadTypes import RelayCache +import Routing import UIKit /** diff --git a/ios/MullvadVPN/Coordinators/App/ChangeLogCoordinator.swift b/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift index 90756c68ce..3437b55f8b 100644 --- a/ios/MullvadVPN/Coordinators/App/ChangeLogCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ChangeLogCoordinator.swift @@ -7,6 +7,7 @@ // import MullvadLogging +import Routing import UIKit final class ChangeLogCoordinator: Coordinator, Presentable { diff --git a/ios/MullvadVPN/Coordinators/App/InAppPurchaseCoordinator.swift b/ios/MullvadVPN/Coordinators/InAppPurchaseCoordinator.swift index 8519ddab04..dc97e680dc 100644 --- a/ios/MullvadVPN/Coordinators/App/InAppPurchaseCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/InAppPurchaseCoordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import StoreKit import UIKit diff --git a/ios/MullvadVPN/Coordinators/App/LoginCoordinator.swift b/ios/MullvadVPN/Coordinators/LoginCoordinator.swift index a659fa5020..0751845e62 100644 --- a/ios/MullvadVPN/Coordinators/App/LoginCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/LoginCoordinator.swift @@ -9,6 +9,7 @@ import MullvadREST import MullvadTypes import Operations +import Routing import UIKit final class LoginCoordinator: Coordinator, DeviceManagementViewControllerDelegate { diff --git a/ios/MullvadVPN/Coordinators/App/OutOfTimeCoordinator.swift b/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift index 5613b8bc6c..a001d2d060 100644 --- a/ios/MullvadVPN/Coordinators/App/OutOfTimeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit class OutOfTimeCoordinator: Coordinator, OutOfTimeViewControllerDelegate { diff --git a/ios/MullvadVPN/Coordinators/App/RevokedCoordinator.swift b/ios/MullvadVPN/Coordinators/RevokedCoordinator.swift index 9bcaccbf16..0942e022e9 100644 --- a/ios/MullvadVPN/Coordinators/App/RevokedCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/RevokedCoordinator.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit final class RevokedCoordinator: Coordinator { diff --git a/ios/MullvadVPN/Coordinators/App/SafariCoordinator.swift b/ios/MullvadVPN/Coordinators/SafariCoordinator.swift index baad824d8d..eca261faea 100644 --- a/ios/MullvadVPN/Coordinators/App/SafariCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/SafariCoordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import SafariServices class SafariCoordinator: Coordinator, Presentable, SFSafariViewControllerDelegate { diff --git a/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift b/ios/MullvadVPN/Coordinators/SelectLocationCoordinator.swift index d29b8eea1b..b813d70bc9 100644 --- a/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/SelectLocationCoordinator.swift @@ -8,6 +8,7 @@ import MullvadTypes import RelayCache +import Routing import UIKit class SelectLocationCoordinator: Coordinator, Presentable, RelayCacheTrackerObserver { diff --git a/ios/MullvadVPN/Coordinators/App/SettingsCoordinator.swift b/ios/MullvadVPN/Coordinators/SettingsCoordinator.swift index 53ce4b3a27..9e48af43ca 100644 --- a/ios/MullvadVPN/Coordinators/App/SettingsCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/SettingsCoordinator.swift @@ -8,6 +8,7 @@ import MullvadLogging import Operations +import Routing import UIKit enum SettingsNavigationRoute: Equatable { diff --git a/ios/MullvadVPN/Coordinators/App/SettingsRedeemVoucherCoordinator.swift b/ios/MullvadVPN/Coordinators/SettingsRedeemVoucherCoordinator.swift index 37fb0fbfe2..c44d670d63 100644 --- a/ios/MullvadVPN/Coordinators/App/SettingsRedeemVoucherCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/SettingsRedeemVoucherCoordinator.swift @@ -8,6 +8,7 @@ import Foundation import MullvadREST +import Routing import UIKit final class SettingsRedeemVoucherCoordinator: Coordinator, Presentable { diff --git a/ios/MullvadVPN/Coordinators/App/SetupAccountCompletedCoordinator.swift b/ios/MullvadVPN/Coordinators/SetupAccountCompletedCoordinator.swift index e2bbe3d42b..93c5532ede 100644 --- a/ios/MullvadVPN/Coordinators/App/SetupAccountCompletedCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/SetupAccountCompletedCoordinator.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import UIKit class SetupAccountCompletedCoordinator: Coordinator, Presenting { diff --git a/ios/MullvadVPN/Coordinators/App/TermsOfServiceCoordinator.swift b/ios/MullvadVPN/Coordinators/TermsOfServiceCoordinator.swift index 5d81981b08..31aa76476e 100644 --- a/ios/MullvadVPN/Coordinators/App/TermsOfServiceCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/TermsOfServiceCoordinator.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit class TermsOfServiceCoordinator: Coordinator, Presenting { diff --git a/ios/MullvadVPN/Coordinators/App/TunnelCoordinator.swift b/ios/MullvadVPN/Coordinators/TunnelCoordinator.swift index 84158992cf..6acb0405c3 100644 --- a/ios/MullvadVPN/Coordinators/App/TunnelCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/TunnelCoordinator.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Mullvad VPN AB. All rights reserved. // +import Routing import UIKit class TunnelCoordinator: Coordinator { diff --git a/ios/MullvadVPN/Coordinators/App/WelcomeCoordinator.swift b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift index 7146155586..33a09b4171 100644 --- a/ios/MullvadVPN/Coordinators/App/WelcomeCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift @@ -8,6 +8,7 @@ import Foundation import MullvadREST +import Routing import StoreKit import UIKit diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsViewController.swift b/ios/MullvadVPN/View controllers/Settings/SettingsViewController.swift index 0fa4479543..3f8e8bf313 100644 --- a/ios/MullvadVPN/View controllers/Settings/SettingsViewController.swift +++ b/ios/MullvadVPN/View controllers/Settings/SettingsViewController.swift @@ -7,6 +7,7 @@ // import Foundation +import Routing import UIKit protocol SettingsViewControllerDelegate: AnyObject { diff --git a/ios/MullvadVPN/Coordinators/Base/Coordinator.swift b/ios/Routing/Coordinator.swift index a72f122257..217a951aef 100644 --- a/ios/MullvadVPN/Coordinators/Base/Coordinator.swift +++ b/ios/Routing/Coordinator.swift @@ -15,7 +15,7 @@ import UIKit Coordinators help to abstract the navigation and business logic from view controllers making them more manageable and reusable. */ -class Coordinator: NSObject { +open class Coordinator: NSObject { /// Private trace log. private lazy var logger = Logger(label: "\(Self.self)") @@ -32,12 +32,12 @@ class Coordinator: NSObject { fileprivate var interactiveDismissalObservers: [(Coordinator) -> Void] = [] /// Child coordinators. - var childCoordinators: [Coordinator] { + public var childCoordinators: [Coordinator] { _children } /// Parent coordinator. - var parent: Coordinator? { + public var parent: Coordinator? { _parent } @@ -48,7 +48,7 @@ class Coordinator: NSObject { Adding the same coordinator twice is a no-op. */ - func addChild(_ child: Coordinator) { + public func addChild(_ child: Coordinator) { guard !_children.contains(child) else { return } _children.append(child) @@ -62,7 +62,7 @@ class Coordinator: NSObject { Removing coordinator that's no longer a child of this coordinator is a no-op. */ - func removeChild(_ child: Coordinator) { + public func removeChild(_ child: Coordinator) { guard let index = _children.firstIndex(where: { $0 == child }) else { return } _children.remove(at: index) @@ -74,7 +74,7 @@ class Coordinator: NSObject { /** Remove coordinator from its parent. */ - func removeFromParent() { + public func removeFromParent() { _parent?.removeChild(self) } } @@ -82,7 +82,7 @@ class Coordinator: NSObject { /** Protocol describing coordinators that can be presented using modal presentation. */ -protocol Presentable: Coordinator { +public protocol Presentable: Coordinator { /** View controller that is presented modally. It's expected it to be the top-most view controller managed by coordinator. @@ -93,7 +93,7 @@ protocol Presentable: Coordinator { /** Protocol describing coordinators that provide modal presentation context. */ -protocol Presenting: Coordinator { +public protocol Presenting: Coordinator { /** View controller providing modal presentation context. */ @@ -106,7 +106,7 @@ extension Presenting { Automatically adds child and removes it upon interactive dismissal. */ - func presentChild( + public func presentChild( _ child: some Presentable, animated: Bool, configuration: ModalPresentationConfiguration = ModalPresentationConfiguration(), @@ -148,7 +148,7 @@ extension Presentable { Automatically removes itself from parent. */ - func dismiss(animated: Bool, completion: (() -> Void)? = nil) { + public func dismiss(animated: Bool, completion: (() -> Void)? = nil) { removeFromParent() presentedViewController.dismiss(animated: animated, completion: completion) @@ -157,7 +157,7 @@ extension Presentable { /** Add block based observer triggered if coordinator is dismissed via user interaction. */ - func onInteractiveDismissal(_ handler: @escaping (Coordinator) -> Void) { + public func onInteractiveDismissal(_ handler: @escaping (Coordinator) -> Void) { interactiveDismissalObservers.append(handler) } } diff --git a/ios/MullvadVPN/Coordinators/Base/ModalPresentationConfiguration.swift b/ios/Routing/ModalPresentationConfiguration.swift index 10581cdfba..d50297fefc 100644 --- a/ios/MullvadVPN/Coordinators/Base/ModalPresentationConfiguration.swift +++ b/ios/Routing/ModalPresentationConfiguration.swift @@ -11,7 +11,7 @@ import UIKit /** A struct holding modal presentation configuration. */ -struct ModalPresentationConfiguration { +public struct ModalPresentationConfiguration { var preferredContentSize: CGSize? var modalPresentationStyle: UIModalPresentationStyle? var modalTransitionStyle: UIModalTransitionStyle? @@ -19,7 +19,23 @@ struct ModalPresentationConfiguration { var transitioningDelegate: UIViewControllerTransitioningDelegate? var presentationControllerDelegate: UIAdaptivePresentationControllerDelegate? - func apply(to vc: UIViewController) { + public init( + preferredContentSize: CGSize? = nil, + modalPresentationStyle: UIModalPresentationStyle? = nil, + modalTransitionStyle: UIModalTransitionStyle? = nil, + isModalInPresentation: Bool? = nil, + transitioningDelegate: UIViewControllerTransitioningDelegate? = nil, + presentationControllerDelegate: UIAdaptivePresentationControllerDelegate? = nil + ) { + self.preferredContentSize = preferredContentSize + self.modalPresentationStyle = modalPresentationStyle + self.modalTransitionStyle = modalTransitionStyle + self.isModalInPresentation = isModalInPresentation + self.transitioningDelegate = transitioningDelegate + self.presentationControllerDelegate = presentationControllerDelegate + } + + public func apply(to vc: UIViewController) { vc.transitioningDelegate = transitioningDelegate if let modalPresentationStyle { @@ -46,7 +62,7 @@ struct ModalPresentationConfiguration { dismissal and calls `dismissalHandler` while proxying all delegate calls to the former delegate. */ - mutating func notifyInteractiveDismissal(_ dismissalHandler: @escaping () -> Void) { + public mutating func notifyInteractiveDismissal(_ dismissalHandler: @escaping () -> Void) { presentationControllerDelegate = PresentationControllerDismissalInterceptor( forwardingTarget: presentationControllerDelegate diff --git a/ios/MullvadVPN/Coordinators/Base/PresentationControllerDismissalInterceptor.swift b/ios/Routing/PresentationControllerDismissalInterceptor.swift index 90d92a8703..90d92a8703 100644 --- a/ios/MullvadVPN/Coordinators/Base/PresentationControllerDismissalInterceptor.swift +++ b/ios/Routing/PresentationControllerDismissalInterceptor.swift diff --git a/ios/MullvadVPN/Routing/AppRouteProtocol.swift b/ios/Routing/Router/AppRouteProtocol.swift index 9411f65e14..1843183958 100644 --- a/ios/MullvadVPN/Routing/AppRouteProtocol.swift +++ b/ios/Routing/Router/AppRouteProtocol.swift @@ -11,7 +11,7 @@ import Foundation /** Formal protocol describing a group of routes. */ -protocol AppRouteGroupProtocol: Comparable, Equatable, Hashable { +public protocol AppRouteGroupProtocol: Comparable, Equatable, Hashable { /** Returns `true` if group is presented modally, otherwise `false` if group is a part of root view controller. @@ -32,7 +32,7 @@ protocol AppRouteGroupProtocol: Comparable, Equatable, Hashable { Default implementation of `Comparable` for `AppRouteGroupProtocol` which compares `modalLevel` of both sides. */ extension AppRouteGroupProtocol { - static func < (lhs: Self, rhs: Self) -> Bool { + public static func < (lhs: Self, rhs: Self) -> Bool { lhs.modalLevel < rhs.modalLevel } } @@ -40,7 +40,7 @@ extension AppRouteGroupProtocol { /** Formal protocol describing a single route. */ -protocol AppRouteProtocol: Equatable, Hashable { +public protocol AppRouteProtocol: Equatable, Hashable { associatedtype RouteGroupType: AppRouteGroupProtocol /** diff --git a/ios/MullvadVPN/Routing/ApplicationRouter.swift b/ios/Routing/Router/ApplicationRouter.swift index b0580d19a6..2de0cbc3ff 100644 --- a/ios/MullvadVPN/Routing/ApplicationRouter.swift +++ b/ios/Routing/Router/ApplicationRouter.swift @@ -13,11 +13,11 @@ import UIKit /** Main application router. */ -final class ApplicationRouter<RouteType: AppRouteProtocol> { +public final class ApplicationRouter<RouteType: AppRouteProtocol> { private let logger = Logger(label: "ApplicationRouter") private(set) var modalStack: [RouteType.RouteGroupType] = [] - private var presentedRoutes: [RouteType.RouteGroupType: [PresentedRoute<RouteType>]] = [:] + private(set) var presentedRoutes: [RouteType.RouteGroupType: [PresentedRoute<RouteType>]] = [:] private var pendingRoutes = [PendingRoute<RouteType>]() private var isProcessingPendingRoutes = false @@ -29,21 +29,21 @@ final class ApplicationRouter<RouteType: AppRouteProtocol> { Delegate object is unonwed and the caller has to guarantee that the router does not outlive it. */ - init(_ delegate: some ApplicationRouterDelegate<RouteType>) { + public init(_ delegate: some ApplicationRouterDelegate<RouteType>) { self.delegate = delegate } /** Returns `true` is the given route group is currently being presented. */ - func isPresenting(group: RouteType.RouteGroupType) -> Bool { + public func isPresenting(group: RouteType.RouteGroupType) -> Bool { modalStack.contains(group) } /** Returns `true` if is the given route is currently being presented. */ - func isPresenting(route: RouteType) -> Bool { + public func isPresenting(route: RouteType) -> Bool { guard let presentedRoute = presentedRoutes[route.routeGroup] else { return false } @@ -53,7 +53,7 @@ final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Enqueue route for presetnation. */ - func present(_ route: RouteType, animated: Bool = true) { + public func present(_ route: RouteType, animated: Bool = true) { enqueue(PendingRoute( operation: .present(route), animated: animated @@ -63,7 +63,7 @@ final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Enqueue dismissal of the route. */ - func dismiss(_ route: RouteType, animated: Bool = true) { + public func dismiss(_ route: RouteType, animated: Bool = true) { enqueue(PendingRoute( operation: .dismiss(.singleRoute(route)), animated: animated @@ -73,7 +73,7 @@ final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Enqueue dismissal of a group of routes. */ - func dismissAll(_ group: RouteType.RouteGroupType, animated: Bool = true) { + public func dismissAll(_ group: RouteType.RouteGroupType, animated: Bool = true) { enqueue(PendingRoute( operation: .dismiss(.group(group)), animated: animated @@ -135,8 +135,8 @@ final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Check if route can be presented above the last route in the modal stack. */ - if let lastRouteGroup = modalStack.last, lastRouteGroup >= route.routeGroup, - route.routeGroup.isModal, route.isExclusive { + if let lastRouteGroup = modalStack.last, route.routeGroup.isModal, + (lastRouteGroup > route.routeGroup) || (route.isExclusive && lastRouteGroup == route.routeGroup) { completion(.blockedByModalContext) return } diff --git a/ios/MullvadVPN/Routing/ApplicationRouterDelegate.swift b/ios/Routing/Router/ApplicationRouterDelegate.swift index 1daa35760e..ecccb15415 100644 --- a/ios/MullvadVPN/Routing/ApplicationRouterDelegate.swift +++ b/ios/Routing/Router/ApplicationRouterDelegate.swift @@ -11,7 +11,7 @@ import Foundation /** Application router delegate */ -protocol ApplicationRouterDelegate<RouteType>: AnyObject { +public protocol ApplicationRouterDelegate<RouteType>: AnyObject { associatedtype RouteType: AppRouteProtocol /** diff --git a/ios/MullvadVPN/Routing/ApplicationRouterTypes.swift b/ios/Routing/Router/ApplicationRouterTypes.swift index 5316e85fdd..1dfd128c0a 100644 --- a/ios/MullvadVPN/Routing/ApplicationRouterTypes.swift +++ b/ios/Routing/Router/ApplicationRouterTypes.swift @@ -116,36 +116,36 @@ enum DismissMatch<RouteType: AppRouteProtocol>: Equatable { /** Struct describing presented route. */ -struct PresentedRoute<RouteType: AppRouteProtocol>: Equatable { - var route: RouteType - var coordinator: Coordinator +public struct PresentedRoute<RouteType: AppRouteProtocol>: Equatable { + public var route: RouteType + public var coordinator: Coordinator } /** Struct holding information used by delegate to perform dismissal of the route(s) in subject. */ -struct RouteDismissalContext<RouteType: AppRouteProtocol> { +public struct RouteDismissalContext<RouteType: AppRouteProtocol> { /** Specific routes that are being dismissed. */ - var dismissedRoutes: [PresentedRoute<RouteType>] + public var dismissedRoutes: [PresentedRoute<RouteType>] /** Whether the entire group is being dismissed. */ - var isClosing: Bool + public var isClosing: Bool /** Whether transition is animated. */ - var isAnimated: Bool + public var isAnimated: Bool } /** Struct holding information used by delegate to perform sub-navigation of the route in subject. */ -struct RouteSubnavigationContext<RouteType: AppRouteProtocol> { - var presentedRoute: PresentedRoute<RouteType> - var route: RouteType - var isAnimated: Bool +public struct RouteSubnavigationContext<RouteType: AppRouteProtocol> { + public var presentedRoute: PresentedRoute<RouteType> + public var route: RouteType + public var isAnimated: Bool } diff --git a/ios/Routing/Routing.h b/ios/Routing/Routing.h new file mode 100644 index 0000000000..2eff63a424 --- /dev/null +++ b/ios/Routing/Routing.h @@ -0,0 +1,19 @@ +// +// Routing.h +// Routing +// +// Created by Jon Petersson on 2023-08-18. +// Copyright © 2023 Mullvad VPN AB. All rights reserved. +// + +#import <Foundation/Foundation.h> + +//! Project version number for Routing. +FOUNDATION_EXPORT double RoutingVersionNumber; + +//! Project version string for Routing. +FOUNDATION_EXPORT const unsigned char RoutingVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import <Routing/PublicHeader.h> + + diff --git a/ios/RoutingTests/RouterBlockDelegate.swift b/ios/RoutingTests/RouterBlockDelegate.swift new file mode 100644 index 0000000000..b1c1f58908 --- /dev/null +++ b/ios/RoutingTests/RouterBlockDelegate.swift @@ -0,0 +1,54 @@ +// +// RouterBlockDelegate.swift +// RoutingTests +// +// Created by Jon Petersson on 2023-08-22. +// Copyright © 2023 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import Routing + +class RouterBlockDelegate<RouteType: AppRouteProtocol>: ApplicationRouterDelegate { + var handleRoute: ((RouteType, Bool, (Coordinator) -> Void) -> Void)? + var handleDismiss: ((RouteDismissalContext<RouteType>, () -> Void) -> Void)? + var shouldPresent: ((RouteType) -> Bool)? + var shouldDismiss: ((RouteDismissalContext<RouteType>) -> Bool)? + var handleSubnavigation: ((RouteSubnavigationContext<RouteType>, () -> Void) -> Void)? + + func applicationRouter( + _ router: ApplicationRouter<RouteType>, + route: RouteType, + animated: Bool, + completion: @escaping (Coordinator) -> Void + ) { + handleRoute?(route, animated, completion) ?? completion(Coordinator()) + } + + func applicationRouter( + _ router: ApplicationRouter<RouteType>, + dismissWithContext context: RouteDismissalContext<RouteType>, + completion: @escaping () -> Void + ) { + handleDismiss?(context, completion) ?? completion() + } + + func applicationRouter(_ router: ApplicationRouter<RouteType>, shouldPresent route: RouteType) -> Bool { + return shouldPresent?(route) ?? true + } + + func applicationRouter( + _ router: ApplicationRouter<RouteType>, + shouldDismissWithContext context: RouteDismissalContext<RouteType> + ) -> Bool { + return shouldDismiss?(context) ?? true + } + + func applicationRouter( + _ router: ApplicationRouter<RouteType>, + handleSubNavigationWithContext context: RouteSubnavigationContext<RouteType>, + completion: @escaping () -> Void + ) { + handleSubnavigation?(context, completion) ?? completion() + } +} diff --git a/ios/RoutingTests/RoutingTests.swift b/ios/RoutingTests/RoutingTests.swift new file mode 100644 index 0000000000..c271a98970 --- /dev/null +++ b/ios/RoutingTests/RoutingTests.swift @@ -0,0 +1,155 @@ +// +// RoutingTests.swift +// MullvadVPNTests +// +// Created by pronebird on 14/08/2023. +// Copyright © 2023 Mullvad VPN AB. All rights reserved. +// + +@testable import Routing +import XCTest + +final class RoutingTests: XCTestCase { + private func createDelegate<T: AppRouteProtocol>(shouldPresent: Bool = true) -> RouterBlockDelegate<T> { + let delegate = RouterBlockDelegate<T>() + + delegate.handleRoute = { _, _, completion in completion(Coordinator()) } + delegate.shouldPresent = { _ in shouldPresent } + + return delegate + } +} + +// MARK: Horizontal flow tests + +extension RoutingTests { + func testPresentHorizontalRoute() throws { + enum TestRoute: AppRouteProtocol { + case one + var isExclusive: Bool { false } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { .horizontal } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate() + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.one) + + XCTAssertTrue(router.isPresenting(route: .one)) + } + + func testShouldDropHorizontalRoute() throws { + enum TestRoute: AppRouteProtocol { + case one + var isExclusive: Bool { false } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { .horizontal } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate(shouldPresent: false) + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.one) + + XCTAssertFalse(router.isPresenting(route: .one)) + } + + func testShouldDropIdenticalHorizontalRouteInSequence() throws { + enum TestRoute: AppRouteProtocol { + case one + var isExclusive: Bool { false } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { .horizontal } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate() + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.one) + router.present(.one) + + XCTAssertEqual(router.presentedRoutes[.horizontal]?.count, 1) + } +} + +// MARK: Modal flow tests + +extension RoutingTests { + func testPresentModalRoutesOfDifferentLevels() throws { + enum TestRoute: AppRouteProtocol { + case one, two + var isExclusive: Bool { false } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { self == .one ? .modalOne : .modalTwo } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate() + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.one) + router.present(.two) + + XCTAssertEqual(router.modalStack.count, 2) + } + + func testPresentModalRoutesOfDifferentLevelsInWrongOrder() throws { + enum TestRoute: AppRouteProtocol { + case one, two + var isExclusive: Bool { false } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { self == .one ? .modalOne : .modalTwo } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate() + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.two) + router.present(.one) + + XCTAssertTrue(router.isPresenting(route: .two)) + XCTAssertEqual(router.modalStack.count, 1) + } + + func testShouldDropSameLevelModalRouteIfPreceededByExclusive() throws { + enum TestRoute: AppRouteProtocol { + case one, two + var isExclusive: Bool { self == .one } + var supportsSubNavigation: Bool { false } + var routeGroup: TestRouteGroup { .modalOne } + } + + let delegate: RouterBlockDelegate<TestRoute> = createDelegate() + let router = ApplicationRouter<TestRoute>(delegate) + + router.present(.one) + router.present(.two) + + XCTAssertTrue(router.isPresenting(route: .one)) + XCTAssertEqual(router.modalStack.count, 1) + } +} + +enum TestRouteGroup: AppRouteGroupProtocol { + case horizontal, modalOne, modalTwo + + var isModal: Bool { + switch self { + case .horizontal: + return false + case .modalOne, .modalTwo: + return true + } + } + + var modalLevel: Int { + switch self { + case .horizontal: + return 0 + case .modalOne: + return 1 + case .modalTwo: + return 2 + } + } +} diff --git a/ios/TestPlans/MullvadVPNApp.xctestplan b/ios/TestPlans/MullvadVPNApp.xctestplan index f0f5d461f0..c802c86036 100644 --- a/ios/TestPlans/MullvadVPNApp.xctestplan +++ b/ios/TestPlans/MullvadVPNApp.xctestplan @@ -56,6 +56,13 @@ "identifier" : "58C7A43C2A863F450060C66F", "name" : "PacketTunnelCoreTests" } + }, + { + "target" : { + "containerPath" : "container:MullvadVPN.xcodeproj", + "identifier" : "7A88DCD62A8FABBE00D2FF0E", + "name" : "RoutingTests" + } } ], "version" : 1 diff --git a/ios/TestPlans/MullvadVPNCI.xctestplan b/ios/TestPlans/MullvadVPNCI.xctestplan index cc3dc95a4e..eff510a5d6 100644 --- a/ios/TestPlans/MullvadVPNCI.xctestplan +++ b/ios/TestPlans/MullvadVPNCI.xctestplan @@ -64,6 +64,14 @@ "identifier" : "58C7A43C2A863F450060C66F", "name" : "PacketTunnelCoreTests" } + }, + { + "parallelizable" : true, + "target" : { + "containerPath" : "container:MullvadVPN.xcodeproj", + "identifier" : "7A88DCD62A8FABBE00D2FF0E", + "name" : "RoutingTests" + } } ], "version" : 1 |
