Introduce an AppMediator which will:

- combine multiple services to handle app wide requests
- remove direct UIApplication access from everywhere
- fix #2703 by combining UIApplication.applicationState with the WindowManager's main window appearance
- leave the door open for more app control in the future (especiall for the mac)
This commit is contained in:
Stefan Ceriu 2024-04-19 13:59:15 +03:00 committed by Stefan Ceriu
parent bdacea10a2
commit 9a172df7fd
30 changed files with 261 additions and 202 deletions

View File

@ -50,6 +50,7 @@
07CC13C5729C24255348CBBD /* ElementCallWidgetDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 309AD8BAE6437C31BA7157BF /* ElementCallWidgetDriver.swift */; };
086D01E79C8E8D3F004FAF21 /* AudioPlayerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC9104846487244648D32C6D /* AudioPlayerProtocol.swift */; };
08CB4BD12CEEDE6AAE4A18DD /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035177BCD8E8308B098AC3C2 /* WindowManager.swift */; };
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; };
095D3906CF2F940C2D2D17CC /* RoomFlowCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCB2126C091EEF2454B4D56 /* RoomFlowCoordinatorTests.swift */; };
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
@ -122,7 +123,6 @@
1AB3D8563AB12635250A6A6E /* StaticLocationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */; };
1AE4AEA0FA8DEF52671832E0 /* RoomTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */; };
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */; };
1B4B3E847BF944DB2C1C217F /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */; };
1B88BB631F7FC45A213BB554 /* TimelineItemSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */; };
1B8E30B35BF8F541C1318F19 /* SecureBackupScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40316EFFEAC7B206EE9A55AE /* SecureBackupScreenViewModelTests.swift */; };
1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */; };
@ -205,7 +205,6 @@
2FEC6652055984389CE1BBEC /* TimelineProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */; };
3042527CB344A9EF1157FC26 /* AudioRecorderStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55CC239AE12339C565F6C9A /* AudioRecorderStateTests.swift */; };
308BD9343B95657FAA583FB7 /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 19CD5B074D7DD44AF4C58BB6 /* SwiftState */; };
3097A0A867D2B19CE32DAE58 /* UIKitBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF1FFC3336EB23374BBBFCC /* UIKitBackgroundTaskService.swift */; };
30CC1DB7CE357659C82AA115 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; };
30CC4F796B27BE8B1DFDBF5A /* NSEUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAA2832D93EC7D2608703FB /* NSEUserSession.swift */; };
30E5628F74AD3C27A061BF25 /* QRCodeLoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC1B7CB061C9865B2B91B56 /* QRCodeLoginScreenViewModel.swift */; };
@ -322,6 +321,7 @@
4BAB8222DBA0B4207D1223E0 /* NotificationSettingsProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */; };
4BB282209EA82015D0DF8F89 /* NavigationStackCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */; };
4BB51476A29E7E27BC14EA22 /* UserDetailsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022E6BD64CB4610B9C95FC02 /* UserDetailsEditScreenViewModel.swift */; };
4BBF6C8E3EFC944B55231B19 /* AppMediatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05AF58372CA884A789EB9C5A /* AppMediatorProtocol.swift */; };
4C356F5CCB4CDC99BFA45185 /* AppLockSetupPINScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7884BD256C091EB511B2EDF /* AppLockSetupPINScreenViewModelProtocol.swift */; };
4C5A638DAA8AF64565BA4866 /* EncryptedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */; };
4C8C0C9FC10BA73AB7780534 /* RoomListFiltersStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE0C9653870803E4F91F474 /* RoomListFiltersStateTests.swift */; };
@ -456,7 +456,6 @@
6BB6944443C421C722ED1E7D /* portrait_test_video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */; };
6C34237AFB808E38FC8776B9 /* RoomStateEventStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */; };
6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3005886F00029F058DB62BE /* StartChatScreenCoordinator.swift */; };
6D046D653DA28ADF1E6E59A4 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */; };
6D6E651ACACE27E9C5690818 /* TypingIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE47A97726F0675DEE387BF9 /* TypingIndicatorView.swift */; };
6DC8E43BA04AC2AC4EB2EB97 /* AnalyticsPromptScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18486B87745B1811E7FBD3D2 /* AnalyticsPromptScreenModels.swift */; };
6E47D126DD7585E8F8237CE7 /* LoadableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */; };
@ -472,7 +471,6 @@
70394ECD2DCC70741538620D /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */; };
70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */; };
706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */; };
706F79A39BDB32F592B8C2C7 /* UIKitBackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */; };
707E49BE07E8EB8A13C0EB1E /* SessionVerificationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */; };
70B83D44043293B4B77440B9 /* PollFormScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */; };
719E7AAD1F8E68F68F30FECD /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; };
@ -485,7 +483,6 @@
73F547BEB41D3DAFAAF6E0AF /* UserProfileScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71E2E5103702D13361D09100 /* UserProfileScreenViewModelTests.swift */; };
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */; };
74604ACFDBE7F54260E7B617 /* ApplicationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */; };
748F482FEF4E04D61C39AAD7 /* EmojiPickerScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */; };
7501442D52A65F73DF79FFD4 /* PaginationIndicatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */; };
754602A7B2AAD443C4228ED4 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 7731767AE437BA3BD2CC14A8 /* Sentry */; };
@ -516,6 +513,7 @@
7A170A5A4A352954BB2A1B96 /* AuthenticationStartScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E8C8817F59BEC7E358EB78 /* AuthenticationStartScreen.swift */; };
7A642EE5F1ADC5D520F21924 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; };
7A71AEF419904209BB8C2833 /* UserAgentBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */; };
7A8B264506D3DDABC01B4EEB /* AppMediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53AC78E49A297AC1D72A7CF /* AppMediator.swift */; };
7B1605C6FFD4D195F264A684 /* RoomPollsHistoryScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40233F2989AD49906BB310D /* RoomPollsHistoryScreenViewModelTests.swift */; };
7B5DAB915357BE596529BF25 /* MapTilerStaticMapProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20872C3887F835958CE2F1D0 /* MapTilerStaticMapProtocol.swift */; };
7B66DA4E7E5FE4D1A0FCEAA4 /* JoinRoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAB5662310AE73D93815134 /* JoinRoomScreenViewModelProtocol.swift */; };
@ -670,7 +668,6 @@
9EBDC79CAC9B63A0D626E333 /* LegalInformationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2CAA266B921D128C35710 /* LegalInformationScreenCoordinator.swift */; };
9F11E743EA01482E78A438B0 /* GlobalSearchScreenCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DB19219E6CC4D002E15D48 /* GlobalSearchScreenCell.swift */; };
9F19096BFA629C0AC282B1E4 /* CreateRoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CEB4634C0DD7779C4AB504 /* CreateRoomScreenUITests.swift */; };
9F30A18B50D13B10D8444984 /* ApplicationMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62011D547772F3DF5D924823 /* ApplicationMock.swift */; };
9FAF6DA7E8E85C9699757764 /* CollapsibleRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E2656184491C505700D2405 /* CollapsibleRoomTimelineView.swift */; };
9FB41B0E8B2AA9B404E52C8B /* AppLockSetupBiometricsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */; };
A009BDFB0A6816D4C392ADCB /* SettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF715D4FD4710EBB637D661 /* SettingsScreenViewModelProtocol.swift */; };
@ -688,6 +685,7 @@
A2434D4DFB49A68E5CD0F53C /* MediaLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A02406480C351B8C6E0682C /* MediaLoaderProtocol.swift */; };
A2A5AB2E8B3F5CA769E531FA /* TextBasedRoomTimelineViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E47F18A9A077E351CEA10D4 /* TextBasedRoomTimelineViewProtocol.swift */; };
A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; };
A36AD251013402EDBD666C75 /* AppMediatorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BAC027034248429A438886B /* AppMediatorMock.swift */; };
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; };
A3A7A05E8F9B7EB0E1A09A2A /* SoftLogoutScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05596E4A11A8C9346E9E54AE /* SoftLogoutScreenCoordinator.swift */; };
A3D7110C1E75E7B4A73BE71C /* VoiceMessageRecorderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93C94C30E3135BC9290DE13 /* VoiceMessageRecorderTests.swift */; };
@ -753,6 +751,7 @@
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */; };
B245583C63F8F90357B87FAE /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = A2AE110B053B55E38F8D10C7 /* KZFileWatchers */; };
B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */; };
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */; };
B3D652AA1654270742072FB3 /* DeveloperOptionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A6F283BC574FDB96ABBB07 /* DeveloperOptionsScreenViewModel.swift */; };
B3EDDEC1839BB5A3747624BB /* FormButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A1CCDEE545CB6453B084BF /* FormButtonStyles.swift */; };
B402708F8728DD0DB7C324E2 /* StartChatScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78910787F967CBC6042A101E /* StartChatScreenViewModelProtocol.swift */; };
@ -851,6 +850,7 @@
C9F5B48D15B9BCAE1F8D564E /* RoomNotificationModeProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */; };
CA12AE0DCD57D49CD96C699A /* WaveformCursorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB9EABCA9348DFA27439A809 /* WaveformCursorView.swift */; };
CA5BFF0C2EF5A8EF40CA2D69 /* VoiceMessageRecordingComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCB6F36CCE44A29A06FCAF1C /* VoiceMessageRecordingComposer.swift */; };
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */; };
CB137BFB3E083C33E398A6CB /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; };
CB498F4E27AA0545DCEF0F6F /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 36B7FC232711031AA2B0D188 /* DTCoreText */; };
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
@ -910,9 +910,11 @@
D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; };
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
D8359F67AF3A83516E9083C1 /* MockUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */; };
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; };
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */; };
D9473FC9B077A6EDB7A12001 /* LocationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772334731A8BF8E6D90B194D /* LocationRoomTimelineView.swift */; };
D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; };
@ -936,7 +938,6 @@
DFD5AA8688A34C72D48AF3B1 /* StaticLocationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */; };
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = F012CB5EE3F2B67359F6CC52 /* target.yml */; };
E07ABB9FD1C87EBBDDE81DC5 /* ResetRecoveryKeyScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63616A8920EC6948B31EA1B /* ResetRecoveryKeyScreenViewModel.swift */; };
E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
E0B6A569AC3E81D233B43D60 /* SettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E625B0EB2F86B37C14EF7E6 /* SettingsScreenViewModel.swift */; };
E0FB26262689F04D66A949D7 /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E227F34BE43B08E098796E /* TestablePreview.swift */; };
E14E469CD97550D0FC58F3CA /* CancellableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52983FAFB4E0998C00EE8A /* CancellableTask.swift */; };
@ -954,6 +955,7 @@
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */; };
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */; };
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
E468CC731C3F4D678499E52F /* LAContextMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA5A62DA4B543827FF82354 /* LAContextMock.swift */; };
E481C8FDCB6C089963C95344 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = BC01130651CB23340B899032 /* DeviceKit */; };
@ -1006,7 +1008,6 @@
EF0D0155DD104C7A41A2EB0E /* PlainMentionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE78FA0011E07920AE83135 /* PlainMentionBuilder.swift */; };
EF47D802A404A53F15D5D4B6 /* JoinRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD7C0A2750998C2D77AD00F /* JoinRoomScreenViewModel.swift */; };
EF5009AC03212227131C8AF2 /* RoomNotificationSettingsProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */; };
EF7924005216B8189898F370 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
EF890DEF0479E66548F2BA23 /* AppLockTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 490BEADEFB2D6B7C9F618AE8 /* AppLockTimer.swift */; };
F0570F1ECD70C4C851FB2052 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E7304F5ECB4CB11CB10E60 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift */; };
F06CE9132855E81EBB6DDC32 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 940C605265DD82DA0C655E23 /* Kingfisher */; };
@ -1157,6 +1158,7 @@
054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionUITests.swift; sourceTree = "<group>"; };
05512FB13987D221B7205DE0 /* HomeScreenRecoveryKeyConfirmationBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRecoveryKeyConfirmationBanner.swift; sourceTree = "<group>"; };
05596E4A11A8C9346E9E54AE /* SoftLogoutScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreenCoordinator.swift; sourceTree = "<group>"; };
05AF58372CA884A789EB9C5A /* AppMediatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediatorProtocol.swift; sourceTree = "<group>"; };
05F598B1B346DAF223651C91 /* LoginScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenCoordinator.swift; sourceTree = "<group>"; };
0685156EB62D7E243F097CFC /* ServerSelectionScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenViewModelProtocol.swift; sourceTree = "<group>"; };
06B098A612DCB5A7358EECD5 /* DeveloperOptionsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreenModels.swift; sourceTree = "<group>"; };
@ -1321,7 +1323,6 @@
2BDB3E65A79779EDA5D33D8A /* AudioPlayerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerState.swift; sourceTree = "<group>"; };
2BFDCA5A09EE70BC17F2EFA7 /* URLComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLComponents.swift; sourceTree = "<group>"; };
2C0197EAE9D45A662B8847B6 /* RoomTimelineControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerProtocol.swift; sourceTree = "<group>"; };
2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
2CEBCB9676FCD1D0F13188DD /* StringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = "<group>"; };
2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
2D0946F77B696176E062D037 /* RoomMembersListScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenModels.swift; sourceTree = "<group>"; };
@ -1338,6 +1339,7 @@
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = "<group>"; };
317F41A4B5C4F457AF710666 /* PollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollView.swift; sourceTree = "<group>"; };
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTaskService.swift; sourceTree = "<group>"; };
31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; };
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsUserDefinedScreen.swift; sourceTree = "<group>"; };
@ -1372,6 +1374,7 @@
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerMock.swift; sourceTree = "<group>"; };
3B5E97E9615A158C76B2AB77 /* DateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTests.swift; sourceTree = "<group>"; };
3BAC027034248429A438886B /* AppMediatorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediatorMock.swift; sourceTree = "<group>"; };
3BC1B7CB061C9865B2B91B56 /* QRCodeLoginScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginScreenViewModel.swift; sourceTree = "<group>"; };
3BDCCD2F6B405C14B9BCE94E /* JoinRoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenCoordinator.swift; sourceTree = "<group>"; };
3C1A3D524D63815B28FA4D62 /* EmojiCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiCategory.swift; sourceTree = "<group>"; };
@ -1388,7 +1391,6 @@
3D9FCE4D1E3A81AC1CC5CB91 /* AppLockSetupSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
3DBE70FFB7936F35811772C1 /* IdentityConfirmedScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreenModels.swift; sourceTree = "<group>"; };
3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingTests.swift; sourceTree = "<group>"; };
3DF1FFC3336EB23374BBBFCC /* UIKitBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTaskService.swift; sourceTree = "<group>"; };
3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = "<group>"; };
3E6A9B9DFEE964962C179DE3 /* RoomAttachmentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomAttachmentPicker.swift; sourceTree = "<group>"; };
3E93A1BE7D8A2EBCAD51EEB4 /* Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = "<group>"; };
@ -1518,7 +1520,6 @@
60F18AECC9D38C2B6D85F99C /* Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.swift; sourceTree = "<group>"; };
612EF972F2A1800682D32C5E /* StickerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineView.swift; sourceTree = "<group>"; };
61B33F23681660E940BA57F4 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/SAS.strings; sourceTree = "<group>"; };
62011D547772F3DF5D924823 /* ApplicationMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationMock.swift; sourceTree = "<group>"; };
622D09D4ECE759189009AEAF /* MapLibreMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreMapView.swift; sourceTree = "<group>"; };
624244C398804ADC885239AA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderTests.swift; sourceTree = "<group>"; };
@ -1644,6 +1645,7 @@
8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmedScreenViewModelProtocol.swift; sourceTree = "<group>"; };
837B440C4705E4B899BCB899 /* RoomDetailsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenViewModel.swift; sourceTree = "<group>"; };
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedCornerShape.swift; sourceTree = "<group>"; };
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskProtocol.swift; sourceTree = "<group>"; };
84311D707B09854D67F78BBF /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersViewModelTests.swift; sourceTree = "<group>"; };
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
@ -1705,7 +1707,6 @@
91CF6F7D08228D16BA69B63B /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.strings"; sourceTree = "<group>"; };
92390F9FA98255440A6BF5F8 /* OIDCAuthenticationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCAuthenticationPresenter.swift; sourceTree = "<group>"; };
92DB574F954CC2B40F7BE892 /* QRCodeScannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeScannerView.swift; sourceTree = "<group>"; };
92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
9332DFE9642F0A46ECA0497B /* BlurHashEncode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
933B074F006F8E930DB98B4E /* TimelineMediaFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaFrame.swift; sourceTree = "<group>"; };
9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenModels.swift; sourceTree = "<group>"; };
@ -1780,7 +1781,6 @@
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = "<group>"; };
A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationProtocol.swift; sourceTree = "<group>"; };
A9B069D7772DDF6513E0F1B8 /* AuthenticationFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationFlowCoordinator.swift; sourceTree = "<group>"; };
A9FAFE1C2149E6AC8156ED2B /* Collection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = "<group>"; };
AA19C32BD97F45847724E09A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Untranslated.strings; sourceTree = "<group>"; };
@ -1788,7 +1788,6 @@
AACE9B8E1A4AE79A7E2914F6 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
AAD01F7FC2BBAC7351948595 /* UserProfile+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserProfile+Mock.swift"; sourceTree = "<group>"; };
AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationAnnotation.swift; sourceTree = "<group>"; };
AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = "<group>"; };
ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
AC0275CEE9CA078B34028BDF /* AppLockScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelTests.swift; sourceTree = "<group>"; };
AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = "<group>"; };
@ -1837,6 +1836,7 @@
B48B7AD4908C5C374517B892 /* MapAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MapAssets.xcassets; sourceTree = "<group>"; };
B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; };
B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = "<group>"; };
B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = "<group>"; };
B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = "<group>"; };
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = "<group>"; };
@ -1965,6 +1965,7 @@
D196116D2DD3F2757D45FCB7 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/SAS.strings; sourceTree = "<group>"; };
D1BC84BA0AF11C2128D58ABD /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
D1D8479BB704B7EF696F8ABE /* RoomPollsHistoryScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenCoordinator.swift; sourceTree = "<group>"; };
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = "<group>"; };
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewVersionPredicate.swift; sourceTree = "<group>"; };
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFlowCoordinator.swift; sourceTree = "<group>"; };
@ -2066,6 +2067,7 @@
EA880E78AF4BD24E45A7808C /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/InfoPlist.strings; sourceTree = "<group>"; };
EAF710CB1C31F8938EAA3A7D /* RoomChangeRolesScreenSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenSection.swift; sourceTree = "<group>"; };
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = "<group>"; };
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = "<group>"; };
EB63761D9F9CE8B23CBD6179 /* PollFormScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenModels.swift; sourceTree = "<group>"; };
EB76A9AFC6CCAD4998D9B045 /* IdentityConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModel.swift; sourceTree = "<group>"; };
EBEB8D9F4940E161B18FE4BC /* UITestsNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsNotificationCenter.swift; sourceTree = "<group>"; };
@ -2325,7 +2327,7 @@
7803E03F759061C948D66B7E /* AppLock */,
FCE7249621F507F34A8122FB /* Audio */,
AAFDD509929A0CCF8BCE51EB /* Authentication */,
EBBEB5471737E9D116DF4738 /* Background */,
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */,
0ED3F5C21537519389C07644 /* BugReport */,
8039515BAA53B7C3275AC64A /* Client */,
8C3BAE06B336D97DABBE2509 /* CreateRoom */,
@ -2682,7 +2684,7 @@
isa = PBXGroup;
children = (
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
62011D547772F3DF5D924823 /* ApplicationMock.swift */,
3BAC027034248429A438886B /* AppMediatorMock.swift */,
E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */,
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */,
D38391154120264910D19528 /* PollMock.swift */,
@ -4333,6 +4335,8 @@
077D7C3BE199B6E5DDEC07EC /* AppCoordinatorStateMachine.swift */,
C75EF87651B00A176AB08E97 /* AppDelegate.swift */,
CA89A2DD51B6BBE1DA55E263 /* Application.swift */,
B53AC78E49A297AC1D72A7CF /* AppMediator.swift */,
05AF58372CA884A789EB9C5A /* AppMediatorProtocol.swift */,
AC3F82523D6F48B926D6AF68 /* AppSettings.swift */,
B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */,
7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */,
@ -4668,6 +4672,17 @@
path = RoomDirectorySearchScreen;
sourceTree = "<group>";
};
C488FC0F4ACF26D0A2C5246E /* BackgroundTasks */ = {
isa = PBXGroup;
children = (
83D7FA960FE1A1A63622CC5E /* BackgroundTaskProtocol.swift */,
D23C089E93ECE0EF83E182ED /* BackgroundTaskServiceProtocol.swift */,
EB49AE5D902C0FE40AF4ADF5 /* UIKitBackgroundTask.swift */,
3199367BC31381F67C870976 /* UIKitBackgroundTaskService.swift */,
);
path = BackgroundTasks;
sourceTree = "<group>";
};
C844840F3DD48A154C65AE0C /* View */ = {
isa = PBXGroup;
children = (
@ -5016,18 +5031,6 @@
path = AccountSettings;
sourceTree = "<group>";
};
EBBEB5471737E9D116DF4738 /* Background */ = {
isa = PBXGroup;
children = (
A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */,
2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */,
AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */,
92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */,
3DF1FFC3336EB23374BBBFCC /* UIKitBackgroundTaskService.swift */,
);
path = Background;
sourceTree = "<group>";
};
EC4545C7E37E8294D3FE6800 /* StartChatScreen */ = {
isa = PBXGroup;
children = (
@ -5658,8 +5661,8 @@
CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */,
BA43D782BE85C7F5F20C624A /* AttributedStringBuilderProtocol.swift in Sources */,
968A5B890004526AB58A217C /* AvatarSize.swift in Sources */,
EF7924005216B8189898F370 /* BackgroundTaskProtocol.swift in Sources */,
1B4B3E847BF944DB2C1C217F /* BackgroundTaskServiceProtocol.swift in Sources */,
08E02C56E8B277A22C5E5BA5 /* BackgroundTaskProtocol.swift in Sources */,
D8ED2FCF46D63A7357E9D502 /* BackgroundTaskServiceProtocol.swift in Sources */,
9A3B0CDF097E3838FB1B9595 /* Bundle.swift in Sources */,
B5618E3C948584E5C1F67033 /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */,
@ -5904,11 +5907,12 @@
4807E8F51DB54F56B25E1C7E /* AppLockSetupSettingsScreenViewModel.swift in Sources */,
C85C7A201E4CFDA477ACEBEB /* AppLockSetupSettingsScreenViewModelProtocol.swift in Sources */,
EF890DEF0479E66548F2BA23 /* AppLockTimer.swift in Sources */,
7A8B264506D3DDABC01B4EEB /* AppMediator.swift in Sources */,
A36AD251013402EDBD666C75 /* AppMediatorMock.swift in Sources */,
4BBF6C8E3EFC944B55231B19 /* AppMediatorProtocol.swift in Sources */,
355B11D08CE0CEF97A813236 /* AppRoutes.swift in Sources */,
12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */,
9462C62798F47E39DCC182D2 /* Application.swift in Sources */,
9F30A18B50D13B10D8444984 /* ApplicationMock.swift in Sources */,
74604ACFDBE7F54260E7B617 /* ApplicationProtocol.swift in Sources */,
61A36B9BB2ADE36CEFF5E98C /* Array.swift in Sources */,
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */,
273AB64B9A26B61C51858867 /* AsyncSequence.swift in Sources */,
@ -5940,8 +5944,8 @@
6146996D5C4DDD5DA816FC87 /* AuthenticationTextFieldStyle.swift in Sources */,
4AAA8606FBA290E23D15422E /* AvatarHeaderView.swift in Sources */,
D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */,
E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */,
6D046D653DA28ADF1E6E59A4 /* BackgroundTaskServiceProtocol.swift in Sources */,
B3066502FA56D9199846C5E7 /* BackgroundTaskProtocol.swift in Sources */,
D798A150BB6569FC07CBEB25 /* BackgroundTaskServiceProtocol.swift in Sources */,
A4B0BAD62A12ED76BD611B79 /* BadgeView.swift in Sources */,
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */,
@ -6537,8 +6541,8 @@
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */,
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
706F79A39BDB32F592B8C2C7 /* UIKitBackgroundTask.swift in Sources */,
3097A0A867D2B19CE32DAE58 /* UIKitBackgroundTaskService.swift in Sources */,
E3E3D645C7F80DD64A86D936 /* UIKitBackgroundTask.swift in Sources */,
CB0C53B67DA62F7E30DDD720 /* UIKitBackgroundTaskService.swift in Sources */,
E96005321849DBD7C72A28F2 /* UITestsAppCoordinator.swift in Sources */,
384D6B9A7DFD7260139D6852 /* UITestsNotificationCenter.swift in Sources */,
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,

View File

@ -24,6 +24,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private let stateMachine: AppCoordinatorStateMachine
private let navigationRootCoordinator: NavigationRootCoordinator
private let userSessionStore: UserSessionStoreProtocol
private let appMediator: AppMediator
private let appSettings: AppSettings
private let appDelegate: AppDelegate
@ -65,6 +66,8 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
init(appDelegate: AppDelegate) {
windowManager = WindowManager(appDelegate: appDelegate)
appMediator = AppMediator(windowManager: windowManager)
Self.setupEnvironmentVariables()
let appSettings = AppSettings()
@ -100,9 +103,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
backgroundTaskService = UIKitBackgroundTaskService {
UIApplication.shared
}
backgroundTaskService = UIKitBackgroundTaskService(appMediator: appMediator)
let keychainController = KeychainController(service: .sessions,
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
@ -409,6 +410,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
authenticationFlowCoordinator = AuthenticationFlowCoordinator(authenticationService: authenticationService,
bugReportService: ServiceLocator.shared.bugReportService,
navigationRootCoordinator: navigationRootCoordinator,
appMediator: appMediator,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
@ -471,6 +473,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
appLockService: appLockFlowCoordinator.appLockService,
bugReportService: ServiceLocator.shared.bugReportService,
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
appMediator: appMediator,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics,
notificationManager: notificationManager,
@ -645,7 +648,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private func handleAppRoute(_ appRoute: AppRoute) {
if let userSessionFlowCoordinator {
userSessionFlowCoordinator.handleAppRoute(appRoute, animated: UIApplication.shared.applicationState == .active)
userSessionFlowCoordinator.handleAppRoute(appRoute, animated: appMediator.appState == .active)
} else {
storedAppRoute = appRoute
}

View File

@ -0,0 +1,68 @@
//
// Copyright 2024 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
class AppMediator: AppMediatorProtocol {
private let windowManager: WindowManagerProtocol
// UIApplication.State won't update if we store this e.g. in the constructor
private var application: UIApplication {
UIApplication.shared
}
init(windowManager: WindowManagerProtocol) {
self.windowManager = windowManager
}
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier {
application.beginBackgroundTask(withName: taskName, expirationHandler: handler)
}
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier) {
application.endBackgroundTask(identifier)
}
func open(_ url: URL) {
application.open(url, options: [:], completionHandler: nil)
}
func openAppSettings() {
guard let url = URL(string: UIApplication.openSettingsURLString) else {
return
}
open(url)
}
var backgroundTimeRemaining: TimeInterval {
application.backgroundTimeRemaining
}
@MainActor
var appState: UIApplication.State {
switch application.applicationState {
case .active:
windowManager.mainWindow.traitCollection.activeAppearance == .active ? .active : .inactive
case .inactive:
.inactive
case .background:
.background
default:
.inactive
}
}
}

View File

@ -18,7 +18,7 @@ import Foundation
import UIKit
// sourcery: AutoMockable
protocol ApplicationProtocol {
protocol AppMediatorProtocol {
func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
func endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier)
@ -29,18 +29,35 @@ protocol ApplicationProtocol {
var backgroundTimeRemaining: TimeInterval { get }
var applicationState: UIApplication.State { get }
var appState: UIApplication.State { get }
}
extension UIApplication: ApplicationProtocol {
func open(_ url: URL) {
open(url, options: [:], completionHandler: nil)
}
func openAppSettings() {
guard let url = URL(string: UIApplication.openSettingsURLString) else {
return
extension UIApplication.State: CustomStringConvertible {
public var description: String {
switch self {
case .active:
return "active"
case .inactive:
return "inactive"
case .background:
return "background"
@unknown default:
return "unknown"
}
}
}
extension UIUserInterfaceActiveAppearance: CustomStringConvertible {
public var description: String {
switch self {
case .active:
return "active"
case .inactive:
return "inactive"
case .unspecified:
return "unspecified"
@unknown default:
return "unknown"
}
open(url)
}
}

View File

@ -27,6 +27,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
private let bugReportService: BugReportServiceProtocol
private let navigationRootCoordinator: NavigationRootCoordinator
private let navigationStackCoordinator: NavigationStackCoordinator
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let userIndicatorController: UserIndicatorControllerProtocol
@ -44,6 +45,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
init(authenticationService: AuthenticationServiceProxyProtocol,
bugReportService: BugReportServiceProtocol,
navigationRootCoordinator: NavigationRootCoordinator,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analytics: AnalyticsService,
userIndicatorController: UserIndicatorControllerProtocol,
@ -51,6 +53,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
self.authenticationService = authenticationService
self.bugReportService = bugReportService
self.navigationRootCoordinator = navigationRootCoordinator
self.appMediator = appMediator
self.appSettings = appSettings
self.analytics = analytics
self.userIndicatorController = userIndicatorController
@ -107,7 +110,8 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
private func startQRCodeLogin() {
let coordinator = QRCodeLoginScreenCoordinator(parameters: .init(qrCodeLoginService: QRCodeLoginService(),
orientationManager: orientationManager))
orientationManager: orientationManager,
appMediator: appMediator))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else {
return

View File

@ -46,6 +46,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private let roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let emojiProvider: EmojiProviderProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let userIndicatorController: UserIndicatorControllerProtocol
@ -73,6 +74,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
emojiProvider: EmojiProviderProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analytics: AnalyticsService,
userIndicatorController: UserIndicatorControllerProtocol,
@ -83,6 +85,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
self.roomTimelineControllerFactory = roomTimelineControllerFactory
self.navigationStackCoordinator = navigationStackCoordinator
self.emojiProvider = emojiProvider
self.appMediator = appMediator
self.appSettings = appSettings
self.analytics = analytics
self.userIndicatorController = userIndicatorController
@ -439,7 +442,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
emojiProvider: emojiProvider,
completionSuggestionService: completionSuggestionService,
appMediator: appMediator,
appSettings: appSettings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
coordinator.actions
.sink { [weak self] action in
@ -714,7 +719,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func presentMapNavigator(interactionMode: StaticLocationInteractionMode) {
let stackCoordinator = NavigationStackCoordinator()
let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode)
let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode, appMediator: appMediator)
let coordinator = StaticLocationScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
@ -1126,6 +1131,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
roomTimelineControllerFactory: roomTimelineControllerFactory,
navigationStackCoordinator: navigationStackCoordinator,
emojiProvider: emojiProvider,
appMediator: appMediator,
appSettings: appSettings,
analytics: analytics,
userIndicatorController: userIndicatorController,

View File

@ -30,6 +30,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private let navigationSplitCoordinator: NavigationSplitCoordinator
private let windowManager: WindowManagerProtocol
private let bugReportService: BugReportServiceProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let notificationManager: NotificationManagerProtocol
@ -71,6 +72,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
appLockService: AppLockServiceProtocol,
bugReportService: BugReportServiceProtocol,
roomTimelineControllerFactory: RoomTimelineControllerFactoryProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analytics: AnalyticsService,
notificationManager: NotificationManagerProtocol,
@ -81,6 +83,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
self.windowManager = windowManager
self.bugReportService = bugReportService
self.roomTimelineControllerFactory = roomTimelineControllerFactory
self.appMediator = appMediator
self.appSettings = appSettings
self.analytics = analytics
self.notificationManager = notificationManager
@ -439,6 +442,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
roomTimelineControllerFactory: roomTimelineControllerFactory,
navigationStackCoordinator: detailNavigationStackCoordinator,
emojiProvider: EmojiProvider(),
appMediator: appMediator,
appSettings: appSettings,
analytics: analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,

View File

@ -16,21 +16,21 @@
import UIKit
extension ApplicationMock {
static var `default`: ApplicationProtocol {
ApplicationMock(withState: .active,
extension AppMediatorMock {
static var `default`: AppMediatorProtocol {
AppMediatorMock(withState: .active,
backgroundTimeRemaining: 10,
allowTasks: true)
}
static var mockBroken: ApplicationProtocol {
ApplicationMock(withState: .inactive,
static var mockBroken: AppMediatorProtocol {
AppMediatorMock(withState: .inactive,
backgroundTimeRemaining: 0,
allowTasks: false)
}
static var mockAboutToSuspend: ApplicationProtocol {
ApplicationMock(withState: .background,
static var mockAboutToSuspend: AppMediatorProtocol {
AppMediatorMock(withState: .background,
backgroundTimeRemaining: 2,
allowTasks: false)
}
@ -42,7 +42,7 @@ extension ApplicationMock {
allowTasks: Bool) {
self.init()
underlyingApplicationState = applicationState
underlyingAppState = applicationState
underlyingBackgroundTimeRemaining = backgroundTimeRemaining
beginBackgroundTaskWithNameExpirationHandlerClosure = { _, handler in

View File

@ -747,17 +747,17 @@ class AppLockServiceMock: AppLockServiceProtocol {
}
}
}
class ApplicationMock: ApplicationProtocol {
class AppMediatorMock: AppMediatorProtocol {
var backgroundTimeRemaining: TimeInterval {
get { return underlyingBackgroundTimeRemaining }
set(value) { underlyingBackgroundTimeRemaining = value }
}
var underlyingBackgroundTimeRemaining: TimeInterval!
var applicationState: UIApplication.State {
get { return underlyingApplicationState }
set(value) { underlyingApplicationState = value }
var appState: UIApplication.State {
get { return underlyingAppState }
set(value) { underlyingAppState = value }
}
var underlyingApplicationState: UIApplication.State!
var underlyingAppState: UIApplication.State!
//MARK: - beginBackgroundTask

View File

@ -19,6 +19,7 @@ import SwiftUI
struct StaticLocationScreenCoordinatorParameters {
let interactionMode: StaticLocationInteractionMode
let appMediator: AppMediatorProtocol
}
enum StaticLocationScreenCoordinatorAction {
@ -27,7 +28,8 @@ enum StaticLocationScreenCoordinatorAction {
}
final class StaticLocationScreenCoordinator: CoordinatorProtocol {
let viewModel: StaticLocationScreenViewModelProtocol
private let parameters: StaticLocationScreenCoordinatorParameters
private let viewModel: StaticLocationScreenViewModelProtocol
private let actionsSubject: PassthroughSubject<StaticLocationScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>()
@ -37,6 +39,8 @@ final class StaticLocationScreenCoordinator: CoordinatorProtocol {
}
init(parameters: StaticLocationScreenCoordinatorParameters) {
self.parameters = parameters
viewModel = StaticLocationScreenViewModel(interactionMode: parameters.interactionMode)
}
@ -49,7 +53,7 @@ final class StaticLocationScreenCoordinator: CoordinatorProtocol {
case .close:
actionsSubject.send(.close)
case .openSystemSettings:
UIApplication.shared.openAppSettings()
parameters.appMediator.openAppSettings()
case .sendLocation(let geoURI, let isUserLocation):
actionsSubject.send(.selectedLocation(geoURI, isUserLocation: isUserLocation))
}

View File

@ -22,6 +22,7 @@ import SwiftUI
struct QRCodeLoginScreenCoordinatorParameters {
let qrCodeLoginService: QRCodeLoginServiceProtocol
let orientationManager: OrientationManagerProtocol
let appMediator: AppMediatorProtocol
}
enum QRCodeLoginScreenCoordinatorAction {
@ -41,7 +42,7 @@ final class QRCodeLoginScreenCoordinator: CoordinatorProtocol {
init(parameters: QRCodeLoginScreenCoordinatorParameters) {
viewModel = QRCodeLoginScreenViewModel(qrCodeLoginService: parameters.qrCodeLoginService,
application: UIApplication.shared)
appMediator: parameters.appMediator)
orientationManager = parameters.orientationManager
}

View File

@ -22,7 +22,7 @@ typealias QRCodeLoginScreenViewModelType = StateStoreViewModel<QRCodeLoginScreen
class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScreenViewModelProtocol {
private let qrCodeLoginService: QRCodeLoginServiceProtocol
private let application: ApplicationProtocol
private let appMediator: AppMediatorProtocol
private let actionsSubject: PassthroughSubject<QRCodeLoginScreenViewModelAction, Never> = .init()
var actionsPublisher: AnyPublisher<QRCodeLoginScreenViewModelAction, Never> {
@ -30,9 +30,9 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
}
init(qrCodeLoginService: QRCodeLoginServiceProtocol,
application: ApplicationProtocol) {
appMediator: AppMediatorProtocol) {
self.qrCodeLoginService = qrCodeLoginService
self.application = application
self.appMediator = appMediator
super.init(initialViewState: QRCodeLoginScreenViewState())
}
@ -45,7 +45,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
case .startScan:
Task { await startScanIfPossible() }
case .openSettings:
application.openAppSettings()
appMediator.openAppSettings()
}
}
@ -56,7 +56,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
/// Only for mocking initial states
fileprivate init(state: QRCodeLoginState) {
qrCodeLoginService = QRCodeLoginServiceMock(configuration: .init())
application = ApplicationMock()
appMediator = AppMediatorMock.default
super.init(initialViewState: .init(state: state))
}
}

View File

@ -27,6 +27,7 @@ struct RoomScreenCoordinatorParameters {
let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol
let emojiProvider: EmojiProviderProtocol
let completionSuggestionService: CompletionSuggestionServiceProtocol
let appMediator: AppMediatorProtocol
let appSettings: AppSettings
}
@ -63,7 +64,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
mediaPlayerProvider: parameters.mediaPlayerProvider,
voiceMessageMediaManager: parameters.voiceMessageMediaManager,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: UIApplication.shared,
appMediator: parameters.appMediator,
appSettings: parameters.appSettings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenter.default)

View File

@ -40,7 +40,7 @@ class RoomScreenInteractionHandler {
private let voiceMessageRecorder: VoiceMessageRecorderProtocol
private let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let application: ApplicationProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analyticsService: AnalyticsService
private let pollInteractionHandler: PollInteractionHandlerProtocol
@ -62,7 +62,7 @@ class RoomScreenInteractionHandler {
voiceMessageMediaManager: VoiceMessageMediaManagerProtocol,
voiceMessageRecorder: VoiceMessageRecorderProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
application: ApplicationProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analyticsService: AnalyticsService) {
self.roomProxy = roomProxy
@ -72,7 +72,7 @@ class RoomScreenInteractionHandler {
self.voiceMessageMediaManager = voiceMessageMediaManager
self.voiceMessageRecorder = voiceMessageRecorder
self.userIndicatorController = userIndicatorController
self.application = application
self.appMediator = appMediator
self.appSettings = appSettings
self.analyticsService = analyticsService
pollInteractionHandler = PollInteractionHandler(analyticsService: analyticsService, roomProxy: roomProxy)
@ -623,7 +623,7 @@ class RoomScreenInteractionHandler {
}
private func openSystemSettings() {
application.openAppSettings()
appMediator.openAppSettings()
}
private func displayMediaActionIfPossible(timelineItem: RoomTimelineItemProtocol) async -> RoomTimelineControllerAction {

View File

@ -32,7 +32,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
private let timelineController: RoomTimelineControllerProtocol
private let mediaPlayerProvider: MediaPlayerProviderProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let application: ApplicationProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analyticsService: AnalyticsService
private let notificationCenter: NotificationCenterProtocol
@ -54,7 +54,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
mediaPlayerProvider: MediaPlayerProviderProtocol,
voiceMessageMediaManager: VoiceMessageMediaManagerProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
application: ApplicationProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analyticsService: AnalyticsService,
notificationCenter: NotificationCenterProtocol) {
@ -64,7 +64,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
self.appSettings = appSettings
self.analyticsService = analyticsService
self.userIndicatorController = userIndicatorController
self.application = application
self.appMediator = appMediator
self.notificationCenter = notificationCenter
let voiceMessageRecorder = VoiceMessageRecorder(audioRecorder: AudioRecorder(), mediaPlayerProvider: mediaPlayerProvider)
@ -76,7 +76,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
voiceMessageMediaManager: voiceMessageMediaManager,
voiceMessageRecorder: voiceMessageRecorder,
userIndicatorController: userIndicatorController,
application: application,
appMediator: appMediator,
appSettings: appSettings,
analyticsService: analyticsService)
@ -417,7 +417,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
}
private func sendReadReceiptIfNeeded(for lastVisibleItemID: TimelineItemIdentifier) async {
guard application.applicationState == .active else { return }
guard appMediator.appState == .active else { return }
await timelineController.sendReadReceipt(for: lastVisibleItemID)
}
@ -659,7 +659,7 @@ extension RoomScreenViewModel {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -58,7 +58,7 @@ struct ReadReceiptsSummaryView_Previews: PreviewProvider, TestablePreview {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: UserIndicatorControllerMock(),
application: ApplicationMock(),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -192,7 +192,7 @@ struct RoomScreen_Previews: PreviewProvider, TestablePreview {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -96,7 +96,7 @@ struct TimelineReadReceiptsView_Previews: PreviewProvider, TestablePreview {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -83,7 +83,7 @@ struct UITimelineView_Previews: PreviewProvider, TestablePreview {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -17,7 +17,6 @@
import Foundation
import UIKit
/// UIKitBackgroundTask is a concrete implementation of BackgroundTaskProtocol using UIApplication background task.
class UIKitBackgroundTask: BackgroundTaskProtocol {
let name: String
var isRunning: Bool {
@ -30,28 +29,21 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
Date().timeIntervalSince(startDate) * 1000
}
private let application: ApplicationProtocol
private let appMediator: AppMediatorProtocol
private var identifier: UIBackgroundTaskIdentifier = .invalid
private var useCounter = 0
private let startDate = Date()
/// Initializes and starts a new background task
/// - Parameters:
/// - name: name
/// - isReusable: flag indicating the task is reusable
/// - application: application instance
/// - expirationHandler: expiration handler
init?(name: String,
isReusable: Bool,
application: ApplicationProtocol,
appMediator: AppMediatorProtocol,
expirationHandler: BackgroundTaskExpirationHandler?) {
self.name = name
self.isReusable = isReusable
self.application = application
self.appMediator = appMediator
self.expirationHandler = expirationHandler
// attempt to start
identifier = application.beginBackgroundTask(withName: name) { [weak self] in
identifier = appMediator.beginBackgroundTask(withName: name) { [weak self] in
guard let self else { return }
self.stop()
self.expirationHandler?(self)
@ -59,13 +51,11 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
if identifier == .invalid {
MXLog.error("Do not start background task: \(name), as OS declined")
// call expiration handler immediately
expirationHandler?(self)
return nil
}
if isReusable {
// creation itself is a use
reuse()
}
@ -94,7 +84,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
if identifier != .invalid {
MXLog.verbose("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)")
application.endBackgroundTask(identifier)
appMediator.endBackgroundTask(identifier)
identifier = .invalid
}
}

View File

@ -19,28 +19,17 @@ import UIKit
/// /// UIKitBackgroundTaskService is a concrete implementation of BackgroundTaskServiceProtocol using a given `ApplicationProtocol` instance.
class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
private let applicationBlock: () -> ApplicationProtocol?
private let appMediator: AppMediatorProtocol
private var reusableTasks = NSMapTable<NSString, UIKitBackgroundTask>(keyOptions: .strongMemory, valueOptions: .weakMemory)
private var application: ApplicationProtocol? {
applicationBlock()
}
/// Initializer
/// - Parameter applicationBlock: block returning the application instance to use. Defaults to a block returning `UIApplication.extensionSafeShared`.
init(withApplicationBlock applicationBlock: @escaping () -> ApplicationProtocol? = { UIApplication.extensionSafeShared }) {
self.applicationBlock = applicationBlock
init(appMediator: AppMediatorProtocol) {
self.appMediator = appMediator
}
func startBackgroundTask(withName name: String,
isReusable: Bool,
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
guard let application else {
MXLog.error("Do not start background task: \(name). Application is nil")
return nil
}
if avoidStartingNewTasks(for: application) {
if shouldAvoidStartingNewTasks() {
MXLog.error("Do not start background task: \(name), as not enough time exists")
// call expiration handler immediately
expirationHandler?()
@ -56,7 +45,7 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
} else {
if let newTask = UIKitBackgroundTask(name: name,
isReusable: isReusable,
application: application,
appMediator: appMediator,
expirationHandler: { [weak self] task in
guard let self else { return }
self.reusableTasks.removeObject(forKey: task.name as NSString)
@ -70,7 +59,7 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
} else {
if let newTask = UIKitBackgroundTask(name: name,
isReusable: isReusable,
application: application,
appMediator: appMediator,
expirationHandler: { _ in
expirationHandler?()
}) {
@ -79,8 +68,8 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
}
}
let appState = application.applicationState
let remainingTime = readableBackgroundTimeRemaining(application.backgroundTimeRemaining)
let appState = appMediator.appState
let remainingTime = readableBackgroundTimeRemaining(appMediator.backgroundTimeRemaining)
MXLog.verbose("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)")
@ -95,9 +84,9 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
}
}
private func avoidStartingNewTasks(for application: ApplicationProtocol) -> Bool {
if application.applicationState == .background,
application.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
private func shouldAvoidStartingNewTasks() -> Bool {
if appMediator.appState == .background,
appMediator.backgroundTimeRemaining < .backgroundTimeRemainingThresholdToStartTasks {
return true
}
return false
@ -107,27 +96,3 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
private extension TimeInterval {
static let backgroundTimeRemainingThresholdToStartTasks: TimeInterval = 5
}
private extension UIApplication {
/// Application instance extension-safe. Will be `nil` on app extensions.
static var extensionSafeShared: UIApplication? {
let selector = NSSelectorFromString("sharedApplication")
guard responds(to: selector) else { return nil }
return perform(selector).takeUnretainedValue() as? UIApplication
}
}
extension UIApplication.State: CustomStringConvertible {
public var description: String {
switch self {
case .active:
return "active"
case .inactive:
return "inactive"
case .background:
return "background"
@unknown default:
return "unknown"
}
}
}

View File

@ -126,6 +126,7 @@ class MockScreen: Identifiable {
let flowCoordinator = AuthenticationFlowCoordinator(authenticationService: MockAuthenticationServiceProxy(),
bugReportService: BugReportServiceMock(),
navigationRootCoordinator: navigationRootCoordinator,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
@ -243,6 +244,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
navigationStackCoordinator.setRootCoordinator(coordinator)
@ -258,6 +260,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
navigationStackCoordinator.setRootCoordinator(coordinator)
@ -273,6 +276,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
navigationStackCoordinator.setRootCoordinator(coordinator)
@ -288,6 +292,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
navigationStackCoordinator.setRootCoordinator(coordinator)
@ -306,6 +311,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -324,6 +330,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -342,6 +349,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -361,6 +369,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -379,6 +388,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -397,6 +407,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -415,6 +426,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -433,6 +445,7 @@ class MockScreen: Identifiable {
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
emojiProvider: EmojiProvider(),
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings)
let coordinator = RoomScreenCoordinator(parameters: parameters)
@ -460,6 +473,7 @@ class MockScreen: Identifiable {
appSettings: ServiceLocator.shared.settings),
bugReportService: BugReportServiceMock(),
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
appMediator: AppMediatorMock.default,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics,
notificationManager: NotificationManagerMock(),

View File

@ -97,8 +97,8 @@ targets:
- path: ../../ElementX/Sources/Other/TestablePreview.swift
- path: ../../ElementX/Sources/Other/Pills/PlainMentionBuilder.swift
- path: ../../ElementX/Sources/Other/Pills/PillConstants.swift
- path: ../../ElementX/Sources/Services/Background/BackgroundTaskProtocol.swift
- path: ../../ElementX/Sources/Services/Background/BackgroundTaskServiceProtocol.swift
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskProtocol.swift
- path: ../../ElementX/Sources/Services/BackgroundTasks/BackgroundTaskServiceProtocol.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift
- path: ../../ElementX/Sources/Services/Media/Provider

View File

@ -24,19 +24,9 @@ class BackgroundTaskTests: XCTestCase {
static let bgTaskName = "test"
}
func testInAnExtension() {
let service = UIKitBackgroundTaskService {
nil
}
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
XCTAssertNil(task, "Task should not be created")
}
func testInitAndStop() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName) else {
XCTFail("Failed to setup test conditions")
return
@ -52,9 +42,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testNotReusableInit() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two not reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName),
@ -69,9 +57,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testReusableInit() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
@ -90,9 +76,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testMultipleStops() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
@ -113,9 +97,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testNotValidReuse() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
@ -135,9 +117,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testValidReuse() {
let service = UIKitBackgroundTaskService {
ApplicationMock.default
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
@ -161,9 +141,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testBrokenApp() {
let service = UIKitBackgroundTaskService {
ApplicationMock.mockBroken
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockBroken)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
@ -172,9 +150,7 @@ class BackgroundTaskTests: XCTestCase {
}
func testNoTimeApp() {
let service = UIKitBackgroundTaskService {
ApplicationMock.mockAboutToSuspend
}
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockAboutToSuspend)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)

View File

@ -32,7 +32,7 @@ class PillContextTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -61,7 +61,7 @@ class PillContextTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -83,7 +83,7 @@ class PillContextTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -202,6 +202,7 @@ class RoomFlowCoordinatorTests: XCTestCase {
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
navigationStackCoordinator: navigationStackCoordinator,
emojiProvider: EmojiProvider(),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,

View File

@ -56,7 +56,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -93,7 +93,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -128,7 +128,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -160,7 +160,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -192,7 +192,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -221,7 +221,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -249,7 +249,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -277,7 +277,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -305,7 +305,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())
@ -425,7 +425,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: notificationCenter)
@ -451,7 +451,7 @@ class RoomScreenViewModelTests: XCTestCase {
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: userIndicatorControllerMock,
application: ApplicationMock.default,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics,
notificationCenter: NotificationCenterMock())

View File

@ -50,6 +50,7 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
appLockService: AppLockServiceMock(),
bugReportService: BugReportServiceMock(),
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
notificationManager: notificationManager,