From e76dbdca3a9c6bbf5ec6f4936a9b061c54fcf3a5 Mon Sep 17 00:00:00 2001 From: "pouria.amini" Date: Tue, 6 Aug 2024 14:00:30 -0700 Subject: [PATCH] fix: track changes to defaultTracking after initialization --- Sources/Amplitude/Configuration.swift | 12 ++- .../Amplitude/DefaultTrackingOptions.swift | 77 ++++++++++++------- Tests/AmplitudeTests/ConfigurationTests.swift | 45 +++++++++++ 3 files changed, 101 insertions(+), 33 deletions(-) diff --git a/Sources/Amplitude/Configuration.swift b/Sources/Amplitude/Configuration.swift index 71aa286f..653db27e 100644 --- a/Sources/Amplitude/Configuration.swift +++ b/Sources/Amplitude/Configuration.swift @@ -33,9 +33,13 @@ public class Configuration { public var identifyBatchIntervalMillis: Int public internal(set) var migrateLegacyData: Bool @available(*, deprecated, renamed: "autocapture", message: "Please use `autocapture` instead.") - /// The SDK no longer tracks changes to the defaultTracking options after initialization. - public var defaultTracking: DefaultTrackingOptions = DefaultTrackingOptions() { - didSet { autocapture = defaultTracking.autocaptureOptions } + public lazy var defaultTracking: DefaultTrackingOptions = { + DefaultTrackingOptions(with: self) + }() { + didSet { + defaultTracking.delegate = self + autocapture = defaultTracking.toAutocaptureOptions + } } public internal(set) var autocapture: AutocaptureOptions public var offline: Bool? @@ -93,7 +97,7 @@ public class Configuration { enableCoppaControl: enableCoppaControl, flushEventsOnClose: flushEventsOnClose, minTimeBetweenSessionsMillis: minTimeBetweenSessionsMillis, - autocapture: defaultTracking.autocaptureOptions, + autocapture: defaultTracking.toAutocaptureOptions, identifyBatchIntervalMillis: identifyBatchIntervalMillis, migrateLegacyData: migrateLegacyData, offline: offline) diff --git a/Sources/Amplitude/DefaultTrackingOptions.swift b/Sources/Amplitude/DefaultTrackingOptions.swift index d128b715..c1edaff8 100644 --- a/Sources/Amplitude/DefaultTrackingOptions.swift +++ b/Sources/Amplitude/DefaultTrackingOptions.swift @@ -10,54 +10,73 @@ public class DefaultTrackingOptions { } public var sessions: Bool { - get { - autocaptureOptions.contains(.sessions) - } - set { - if newValue { - autocaptureOptions.insert(.sessions) - } else { - autocaptureOptions.remove(.sessions) - } + didSet { + delegate?.didChangeSessions(to: sessions) } } public var appLifecycles: Bool { - get { - autocaptureOptions.contains(.appLifecycles) - } - set { - if newValue { - autocaptureOptions.insert(.appLifecycles) - } else { - autocaptureOptions.remove(.appLifecycles) - } + didSet { + delegate?.didChangeAppLifecycles(to: appLifecycles) } } public var screenViews: Bool { - get { - autocaptureOptions.contains(.screenViews) - } - set { - if newValue { - autocaptureOptions.insert(.screenViews) - } else { - autocaptureOptions.remove(.screenViews) - } + didSet { + delegate?.didChangeScreenViews(to: screenViews) } } - var autocaptureOptions: AutocaptureOptions + weak var delegate: DefaultTrackingOptionsDelegate? + + var toAutocaptureOptions: AutocaptureOptions { + return [ + sessions ? .sessions : [], + appLifecycles ? .appLifecycles : [], + screenViews ? .screenViews : [] + ].reduce(into: []) { $0.formUnion($1) } + } public init( sessions: Bool = true, appLifecycles: Bool = false, screenViews: Bool = false ) { - self.autocaptureOptions = [] self.sessions = sessions self.appLifecycles = appLifecycles self.screenViews = screenViews } + + convenience init(with delegate: DefaultTrackingOptionsDelegate) { + self.init() + self.delegate = delegate + } +} + +protocol DefaultTrackingOptionsDelegate: AnyObject { + func didChangeSessions(to newValue: Bool) + func didChangeAppLifecycles(to newValue: Bool) + func didChangeScreenViews(to newValue: Bool) +} + +extension Configuration: DefaultTrackingOptionsDelegate { + func didChangeSessions(to newValue: Bool) { + updateAutocapture(option: .sessions, enabled: newValue) + } + + func didChangeAppLifecycles(to newValue: Bool) { + updateAutocapture(option: .appLifecycles, enabled: newValue) + } + + func didChangeScreenViews(to newValue: Bool) { + updateAutocapture(option: .screenViews, enabled: newValue) + } + + private func updateAutocapture(option: AutocaptureOptions, enabled: Bool) { + if enabled { + autocapture.insert(option) + } else { + autocapture.remove(option) + } + } } diff --git a/Tests/AmplitudeTests/ConfigurationTests.swift b/Tests/AmplitudeTests/ConfigurationTests.swift index e39eb770..a37ec20f 100644 --- a/Tests/AmplitudeTests/ConfigurationTests.swift +++ b/Tests/AmplitudeTests/ConfigurationTests.swift @@ -88,4 +88,49 @@ final class ConfigurationTests: XCTestCase { XCTAssertTrue(eventStorageUrl?.contains(expectedStoragePostfix) ?? false) XCTAssertTrue(identifyStorageUrl?.contains(expectedStoragePostfix) ?? false) } + + func testDefaultTrackingOptionChangesReflectInAutocapture() { + let configuration = Configuration( + apiKey: "test-api-key" + ) + + XCTAssertTrue(configuration.autocapture.contains(.sessions)) + + (configuration as DeprecationWarningDiscardable).setDefaulTracking(sessions: false, appLifecycles: true, screenViews: true) + + XCTAssertFalse(configuration.autocapture.contains(.sessions)) + XCTAssertTrue(configuration.autocapture.contains(.appLifecycles)) + XCTAssertTrue(configuration.autocapture.contains(.screenViews)) + } + + func testDefaultTrackingInstanceChangeReflectInAutocapture() { + let configuration = Configuration( + apiKey: "test-api-key" + ) + + (configuration as DeprecationWarningDiscardable).setDefaulTracking(sessions: false, appLifecycles: true, screenViews: true) + + XCTAssertFalse(configuration.autocapture.contains(.sessions)) + XCTAssertTrue(configuration.autocapture.contains(.appLifecycles)) + XCTAssertTrue(configuration.autocapture.contains(.screenViews)) + } +} + +private protocol DeprecationWarningDiscardable { + func setDefaulTracking(sessions: Bool, appLifecycles: Bool, screenViews: Bool) + func setDefaulTrackingOptions(sessions: Bool, appLifecycles: Bool, screenViews: Bool) +} + +extension Configuration: DeprecationWarningDiscardable { + @available(*, deprecated) + func setDefaulTracking(sessions: Bool, appLifecycles: Bool, screenViews: Bool) { + defaultTracking = DefaultTrackingOptions(sessions: sessions, appLifecycles: appLifecycles, screenViews: screenViews) + } + + @available(*, deprecated) + func setDefaulTrackingOptions(sessions: Bool, appLifecycles: Bool, screenViews: Bool) { + defaultTracking.sessions = sessions + defaultTracking.appLifecycles = appLifecycles + defaultTracking.screenViews = screenViews + } }