Resetting the app after deletion and cleanup settings (#372)

* Fixes #361 - Reset everything if the app has been deleted since the last run

* Cleaned up and renamed the ElementSettings to ApplicationSettings. Removed its singleton and moved it to the service locator.

* Moved the ApplicationSettings to the Application folder

* Merged together the BuildSettings and ApplicationSettings

* Reset the UserDefaults too when resetting the application state

* Rename ServiceLocator.applicationSettings to just settings

* Fix indentation

* Rename ApplicationSettings to AppSettings

* Various tweaks following code review

* Fix unit tests
This commit is contained in:
Stefan Ceriu
2022-12-16 10:02:22 +02:00
committed by GitHub
parent 5b90f37f2e
commit 6f974a4422
39 changed files with 259 additions and 272 deletions
@@ -49,14 +49,14 @@ class Analytics {
/// Whether to show the user the analytics opt in prompt.
var shouldShowAnalyticsPrompt: Bool {
// Only show the prompt once, and when analytics are enabled in BuildSettings.
!ElementSettings.shared.hasSeenAnalyticsPrompt && BuildSettings.analyticsConfiguration.isEnabled
!ServiceLocator.shared.settings.hasSeenAnalyticsPrompt && ServiceLocator.shared.settings.analyticsConfiguration.isEnabled
}
/// Opts in to analytics tracking with the supplied user session.
/// - Parameter userSession: The user session to use to when reading/generating the analytics ID.
/// The session will be ignored if not running.
func optIn(with userSession: UserSessionProtocol) {
ElementSettings.shared.enableAnalytics = true
ServiceLocator.shared.settings.enableAnalytics = true
startIfEnabled()
Task { await useAnalyticsSettings(from: userSession) }
@@ -64,7 +64,7 @@ class Analytics {
/// Stops analytics tracking and calls `reset` to clear any IDs and event queues.
func optOut() {
ElementSettings.shared.enableAnalytics = false
ServiceLocator.shared.settings.enableAnalytics = false
// The order is important here. PostHog ignores the reset if stopped.
reset()
@@ -76,7 +76,7 @@ class Analytics {
/// Starts the analytics client if the user has opted in, otherwise does nothing.
func startIfEnabled() {
guard ElementSettings.shared.enableAnalytics, !isRunning else { return }
guard ServiceLocator.shared.settings.enableAnalytics, !isRunning else { return }
client.start()
// monitoringClient.start()
@@ -96,8 +96,8 @@ class Analytics {
/// - Parameter userSession: The user session to read analytics settings from.
func useAnalyticsSettings(from userSession: UserSessionProtocol) async {
guard
ElementSettings.shared.enableAnalytics,
!ElementSettings.shared.isIdentifiedForAnalytics
ServiceLocator.shared.settings.enableAnalytics,
!ServiceLocator.shared.settings.isIdentifiedForAnalytics
else { return }
let service = AnalyticsService(userSession: userSession)
@@ -122,7 +122,7 @@ class Analytics {
// monitoringClient.reset()
MXLog.debug("Reset.")
ElementSettings.shared.isIdentifiedForAnalytics = false
ServiceLocator.shared.settings.isIdentifiedForAnalytics = false
// Stop collecting crash logs
// MXLogger.logCrashes(false)
@@ -147,7 +147,7 @@ class Analytics {
client.identify(id: id)
MXLog.debug("Identified.")
ElementSettings.shared.isIdentifiedForAnalytics = true
ServiceLocator.shared.settings.isIdentifiedForAnalytics = true
}
/// Capture an event in the `client`.
@@ -18,7 +18,7 @@ import PostHog
extension PHGPostHogConfiguration {
static var standard: PHGPostHogConfiguration? {
let analyticsConfiguration = BuildSettings.analyticsConfiguration
let analyticsConfiguration = ServiceLocator.shared.settings.analyticsConfiguration
guard analyticsConfiguration.isEnabled else { return nil }
let postHogConfiguration = PHGPostHogConfiguration(apiKey: analyticsConfiguration.apiKey, host: analyticsConfiguration.host)
@@ -22,7 +22,7 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
private let authenticationService: AuthenticationService
private let userSessionStore: UserSessionStoreProtocol
private(set) var homeserver = LoginHomeserver(address: BuildSettings.defaultHomeserverAddress, loginMode: .unknown)
private(set) var homeserver = LoginHomeserver(address: ServiceLocator.shared.settings.defaultHomeserverAddress, loginMode: .unknown)
init(userSessionStore: UserSessionStoreProtocol) {
self.userSessionStore = userSessionStore
@@ -28,7 +28,7 @@ class BugReportService: BugReportServiceProtocol {
init(withBaseURL baseURL: URL,
sentryURL: URL,
applicationId: String = BuildSettings.bugReportApplicationId,
applicationId: String = ServiceLocator.shared.settings.bugReportApplicationId,
session: URLSession = .shared) {
self.baseURL = baseURL
self.sentryURL = sentryURL
@@ -81,7 +81,7 @@ class ClientProxy: ClientProxyProtocol {
await Task.dispatch(on: clientQueue) {
do {
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ElementSettings.shared.slidingSyncProxyBaseURLString)
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ServiceLocator.shared.settings.slidingSyncProxyBaseURLString)
let slidingSyncView = try SlidingSyncViewBuilder()
.timelineLimit(limit: 10)
@@ -89,12 +89,12 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
do {
try await clientProxy.setPusher(pushkey: deviceToken.base64EncodedString(),
kind: .http,
appId: BuildSettings.pusherAppId,
appId: ServiceLocator.shared.settings.pusherAppId,
appDisplayName: "\(InfoPlistReader.target.bundleDisplayName) (iOS)",
deviceDisplayName: UIDevice.current.name,
profileTag: pusherProfileTag(),
lang: Bundle.preferredLanguages.first ?? "en",
url: BuildSettings.pushGatewayBaseURL.absoluteString,
url: ServiceLocator.shared.settings.pushGatewayBaseURL.absoluteString,
format: .eventIdOnly,
defaultPayload: [
"aps": [
@@ -113,7 +113,7 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
}
private func pusherProfileTag() -> String {
if let currentTag = ElementSettings.shared.pusherProfileTag {
if let currentTag = ServiceLocator.shared.settings.pusherProfileTag {
return currentTag
}
let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
@@ -122,7 +122,7 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
return String(chars[chars.index(chars.startIndex, offsetBy: offset)])
}.joined()
ElementSettings.shared.pusherProfileTag = newTag
ServiceLocator.shared.settings.pusherProfileTag = newTag
return newTag
}
}
@@ -132,7 +132,7 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
extension NotificationManager: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
guard ElementSettings.shared.enableInAppNotifications else {
guard ServiceLocator.shared.settings.enableInAppNotifications else {
return []
}
guard let delegate else {
@@ -36,6 +36,12 @@ class UserSessionStore: UserSessionStoreProtocol {
MXLog.debug("Setup base directory at: \(baseDirectory)")
}
/// Deletes all data stored in the shared container and keychain
func reset() {
try? FileManager.default.removeItem(at: baseDirectory)
keychainController.removeAllRestorationTokens()
}
func restoreUserSession() async -> Result<UserSession, UserSessionStoreError> {
let availableCredentials = keychainController.restorationTokens()
@@ -25,6 +25,9 @@ enum UserSessionStoreError: Error {
}
protocol UserSessionStoreProtocol {
/// Deletes all data stored in the shared container and keychain
func reset()
/// Whether or not there are sessions in the store.
var hasSessions: Bool { get }