Initial skeleton for Universal Link handling.

This commit is contained in:
Doug 2023-09-05 17:21:53 +01:00 committed by Stefan Ceriu
parent 1a12c729de
commit b9279ce709
5 changed files with 37 additions and 15 deletions

View File

@ -24,6 +24,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
private let stateMachine: AppCoordinatorStateMachine
private let navigationRootCoordinator: NavigationRootCoordinator
private let userSessionStore: UserSessionStoreProtocol
private let appSettings: AppSettings
/// Common background task to continue long-running tasks in the background.
private var backgroundTask: BackgroundTaskProtocol?
@ -71,6 +72,8 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
AppSettings.reset()
}
self.appSettings = appSettings
navigationRootCoordinator = NavigationRootCoordinator()
Self.setupServiceLocator(navigationRootCoordinator: navigationRootCoordinator, appSettings: appSettings)
@ -88,7 +91,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
userSessionStore = UserSessionStore(backgroundTaskService: backgroundTaskService)
notificationManager = NotificationManager(notificationCenter: UNUserNotificationCenter.current(),
appSettings: ServiceLocator.shared.settings)
appSettings: appSettings)
notificationManager.delegate = self
notificationManager.start()
@ -96,13 +99,13 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
fatalError("The app's version number **must** use semver for migration purposes.")
}
if let previousVersion = ServiceLocator.shared.settings.lastVersionLaunched.flatMap(Version.init) {
if let previousVersion = appSettings.lastVersionLaunched.flatMap(Version.init) {
performMigrationsIfNecessary(from: previousVersion, to: currentVersion)
} else {
// The app has been deleted since the previous run. Reset everything.
wipeUserData(includingSettings: true)
}
ServiceLocator.shared.settings.lastVersionLaunched = currentVersion.description
appSettings.lastVersionLaunched = currentVersion.description
setupStateMachine()
@ -132,6 +135,15 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
)
}
func handleUniversalLink(_ url: URL) {
// Parse into an AppRoute to redirect these in a type safe way.
// Until we have an OIDC callback AppRoute, handle it manually.
if url.absoluteString.starts(with: appSettings.oidcRedirectURL.absoluteString) {
MXLog.error("OIDC callback through Universal Links not implemented.")
}
}
// MARK: - AuthenticationCoordinatorDelegate
func authenticationCoordinator(_ authenticationCoordinator: AuthenticationCoordinator, didLoginWithSession userSession: UserSessionProtocol) {
@ -207,13 +219,13 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
ServiceLocator.shared.register(userIndicatorController: UserIndicatorController(rootCoordinator: navigationRootCoordinator))
ServiceLocator.shared.register(appSettings: appSettings)
ServiceLocator.shared.register(networkMonitor: NetworkMonitor())
ServiceLocator.shared.register(bugReportService: BugReportService(withBaseURL: ServiceLocator.shared.settings.bugReportServiceBaseURL,
sentryURL: ServiceLocator.shared.settings.bugReportSentryURL,
applicationId: ServiceLocator.shared.settings.bugReportApplicationId,
ServiceLocator.shared.register(bugReportService: BugReportService(withBaseURL: appSettings.bugReportServiceBaseURL,
sentryURL: appSettings.bugReportSentryURL,
applicationId: appSettings.bugReportApplicationId,
sdkGitSHA: sdkGitSha(),
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize))
maxUploadSize: appSettings.bugReportMaxUploadSize))
ServiceLocator.shared.register(analytics: AnalyticsService(client: PostHogAnalyticsClient(),
appSettings: ServiceLocator.shared.settings,
appSettings: appSettings,
bugReportService: ServiceLocator.shared.bugReportService))
}
@ -231,7 +243,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
if oldVersion < Version(1, 1, 7) {
MXLog.info("Migrating to v1.1.0, marking accounts as migrated.")
for userID in userSessionStore.userIDs {
ServiceLocator.shared.settings.migratedAccounts[userID] = true
appSettings.migratedAccounts[userID] = true
}
}
}
@ -300,10 +312,10 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
private func startAuthentication() {
let authenticationNavigationStackCoordinator = NavigationStackCoordinator()
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: ServiceLocator.shared.settings)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: appSettings)
authenticationCoordinator = AuthenticationCoordinator(authenticationService: authenticationService,
navigationStackCoordinator: authenticationNavigationStackCoordinator,
appSettings: ServiceLocator.shared.settings,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
authenticationCoordinator?.delegate = self
@ -329,7 +341,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
userDisplayName: displayName,
deviceID: userSession.deviceID)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: ServiceLocator.shared.settings)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: appSettings)
_ = await authenticationService.configure(for: userSession.homeserver)
let parameters = SoftLogoutScreenCoordinatorParameters(authenticationService: authenticationService,
@ -361,7 +373,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
navigationSplitCoordinator: navigationSplitCoordinator,
bugReportService: ServiceLocator.shared.bugReportService,
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
appSettings: ServiceLocator.shared.settings,
appSettings: appSettings,
analytics: ServiceLocator.shared.analytics)
userSessionFlowCoordinator.callback = { [weak self] action in
@ -668,7 +680,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
// MARK: Background app refresh
private func registerBackgroundAppRefresh() {
let result = BGTaskScheduler.shared.register(forTaskWithIdentifier: ServiceLocator.shared.settings.backgroundAppRefreshTaskIdentifier, using: .main) { [weak self] task in
let result = BGTaskScheduler.shared.register(forTaskWithIdentifier: appSettings.backgroundAppRefreshTaskIdentifier, using: .main) { [weak self] task in
guard let task = task as? BGAppRefreshTask else {
MXLog.error("Invalid background app refresh configuration")
return
@ -681,7 +693,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
}
private func scheduleBackgroundAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: ServiceLocator.shared.settings.backgroundAppRefreshTaskIdentifier)
let request = BGAppRefreshTaskRequest(identifier: appSettings.backgroundAppRefreshTaskIdentifier)
// We have other background tasks that keep the app alive
request.earliestBeginDate = Date(timeIntervalSinceNow: 30)

View File

@ -18,4 +18,5 @@ import Foundation
protocol AppCoordinatorProtocol: CoordinatorProtocol {
var notificationManager: NotificationManagerProtocol { get }
func handleUniversalLink(_ url: URL)
}

View File

@ -35,6 +35,7 @@ struct Application: App {
WindowGroup {
appCoordinator.toPresentable()
.statusBarHidden(shouldHideStatusBar)
.onOpenURL { appCoordinator.handleUniversalLink($0) }
.introspect(.window, on: .iOS(.v16)) { window in
// Workaround for SwiftUI not consistently applying the tint colour to Alerts/Confirmation Dialogs.
window.tintColor = .compound.textActionPrimary

View File

@ -60,6 +60,10 @@ class UITestsAppCoordinator: AppCoordinatorProtocol {
func toPresentable() -> AnyView {
navigationRootCoordinator.toPresentable()
}
func handleUniversalLink(_ url: URL) {
fatalError("Not implemented.")
}
}
@MainActor

View File

@ -36,4 +36,8 @@ class UnitTestsAppCoordinator: AppCoordinatorProtocol {
func toPresentable() -> AnyView {
AnyView(ProgressView("Running Unit Tests"))
}
func handleUniversalLink(_ url: URL) {
fatalError("Not implemented.")
}
}