Skip to content

Commit cc76cff

Browse files
committed
feat: Allow for more granular tracked lifecycle events to track
1 parent 7d47f4b commit cc76cff

File tree

5 files changed

+135
-95
lines changed

5 files changed

+135
-95
lines changed

Sources/Segment/Configuration.swift

+53-2
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,50 @@ public enum StorageMode {
4848
// MARK: - Internal Configuration
4949

5050
public class Configuration {
51+
@objc(SEGTrackedLifecycleEvent)
52+
public final class TrackedLifecycleEvent: NSObject, OptionSet {
53+
public let rawValue: Int
54+
55+
public init(rawValue: Int) {
56+
self.rawValue = rawValue
57+
}
58+
59+
public static let none = TrackedLifecycleEvent()
60+
public static let applicationInstalled = TrackedLifecycleEvent(rawValue: 0b00000001)
61+
public static let applicationUpdated = TrackedLifecycleEvent(rawValue: 0b00000010)
62+
public static let applicationOpened = TrackedLifecycleEvent(rawValue: 0b00000100)
63+
public static let applicationBackgrounded = TrackedLifecycleEvent(rawValue: 0b00001000)
64+
public static let applicationForegrounded = TrackedLifecycleEvent(rawValue: 0b00010000)
65+
#if os(macOS)
66+
public static let applicationUnhidden = TrackedLifecycleEvent(rawValue: 0b00100000)
67+
public static let applicationHidden = TrackedLifecycleEvent(rawValue: 0b01000000)
68+
public static let applicationTerminated = TrackedLifecycleEvent(rawValue: 0b10000000)
69+
70+
public static let all = TrackedLifecycleEvent([
71+
applicationInstalled,
72+
applicationUpdated,
73+
applicationOpened,
74+
applicationBackgrounded,
75+
applicationForegrounded,
76+
applicationUnhidden,
77+
applicationHidden,
78+
applicationTerminated,
79+
])
80+
#elseif os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst)
81+
public static let all = TrackedLifecycleEvent([
82+
applicationInstalled,
83+
applicationUpdated,
84+
applicationOpened,
85+
applicationBackgrounded,
86+
applicationForegrounded,
87+
])
88+
#endif
89+
}
90+
5191
internal struct Values {
5292
var writeKey: String
5393
var application: Any? = nil
54-
var trackApplicationLifecycleEvents: Bool = true
94+
var trackedApplicationLifecycleEvents = TrackedLifecycleEvent.all
5595
var flushAt: Int = 20
5696
var flushInterval: TimeInterval = 30
5797
var defaultSettings: Settings? = nil
@@ -110,8 +150,19 @@ public extension Configuration {
110150
/// - Parameter enabled: A bool value
111151
/// - Returns: The current Configuration.
112152
@discardableResult
153+
@available(*, deprecated, message: "Use `setTrackedApplicationLifecycleEvents(_:)` for more granular control")
113154
func trackApplicationLifecycleEvents(_ enabled: Bool) -> Configuration {
114-
values.trackApplicationLifecycleEvents = enabled
155+
values.trackedApplicationLifecycleEvents = enabled ? .all : .none
156+
return self
157+
}
158+
159+
/// Opt-in/out of tracking lifecycle events. The default value is `.none`.
160+
///
161+
/// - Parameter events: An option set of the events to track.
162+
/// - Returns: The current Configuration.
163+
@discardableResult
164+
func setTrackedApplicationLifecycleEvents(_ events: TrackedLifecycleEvent) -> Configuration {
165+
values.trackedApplicationLifecycleEvents = events
115166
return self
116167
}
117168

Sources/Segment/ObjC/ObjCConfiguration.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ public class ObjCConfiguration: NSObject {
2929

3030
/// Opt-in/out of tracking lifecycle events. The default value is `false`.
3131
@objc
32-
public var trackApplicationLifecycleEvents: Bool {
32+
public var trackApplicationLifecycleEvents: Configuration.TrackedLifecycleEvent {
3333
get {
34-
return configuration.values.trackApplicationLifecycleEvents
34+
return configuration.values.trackedApplicationLifecycleEvents
3535
}
3636
set(value) {
37-
configuration.trackApplicationLifecycleEvents(value)
37+
configuration.setTrackedApplicationLifecycleEvents(value)
3838
}
3939
}
4040

Sources/Segment/Plugins/Platforms/Mac/macOSLifecycleEvents.swift

+36-43
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ class macOSLifecycleEvents: PlatformPlugin, macOSLifecycle {
2828
// Make sure we aren't double calling application:didFinishLaunchingWithOptions
2929
// by resetting the check at the start
3030
_didFinishLaunching.set(true)
31-
32-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
33-
return
34-
}
3531

3632
let previousVersion = UserDefaults.standard.string(forKey: Self.versionKey)
3733
let previousBuild = UserDefaults.standard.string(forKey: Self.buildKey)
@@ -40,64 +36,63 @@ class macOSLifecycleEvents: PlatformPlugin, macOSLifecycle {
4036
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
4137

4238
if previousBuild == nil {
43-
analytics?.track(name: "Application Installed", properties: [
44-
"version": currentVersion ?? "",
45-
"build": currentBuild ?? ""
46-
])
39+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationInstalled) == true {
40+
analytics?.track(name: "Application Installed", properties: [
41+
"version": currentVersion ?? "",
42+
"build": currentBuild ?? ""
43+
])
44+
}
4745
} else if currentBuild != previousBuild {
48-
analytics?.track(name: "Application Updated", properties: [
49-
"previous_version": previousVersion ?? "",
50-
"previous_build": previousBuild ?? "",
46+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationUpdated) == true {
47+
analytics?.track(name: "Application Updated", properties: [
48+
"previous_version": previousVersion ?? "",
49+
"previous_build": previousBuild ?? "",
50+
"version": currentVersion ?? "",
51+
"build": currentBuild ?? ""
52+
])
53+
}
54+
}
55+
56+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationOpened) == true {
57+
analytics?.track(name: "Application Opened", properties: [
58+
"from_background": false,
5159
"version": currentVersion ?? "",
5260
"build": currentBuild ?? ""
5361
])
5462
}
55-
56-
analytics?.track(name: "Application Opened", properties: [
57-
"from_background": false,
58-
"version": currentVersion ?? "",
59-
"build": currentBuild ?? ""
60-
])
61-
63+
6264
UserDefaults.standard.setValue(currentVersion, forKey: Self.versionKey)
6365
UserDefaults.standard.setValue(currentBuild, forKey: Self.buildKey)
6466
}
6567

6668
func applicationDidUnhide() {
67-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
68-
return
69+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationUnhidden) == true {
70+
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
71+
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
72+
73+
analytics?.track(name: "Application Unhidden", properties: [
74+
"from_background": true,
75+
"version": currentVersion ?? "",
76+
"build": currentBuild ?? ""
77+
])
6978
}
70-
71-
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
72-
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
73-
74-
analytics?.track(name: "Application Unhidden", properties: [
75-
"from_background": true,
76-
"version": currentVersion ?? "",
77-
"build": currentBuild ?? ""
78-
])
7979
}
8080

8181
func applicationDidHide() {
82-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
83-
return
82+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationHidden) == true {
83+
analytics?.track(name: "Application Hidden")
8484
}
85-
86-
analytics?.track(name: "Application Hidden")
8785
}
8886
func applicationDidResignActive() {
89-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
90-
return
87+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationBackgrounded) == true {
88+
analytics?.track(name: "Application Backgrounded")
9189
}
92-
93-
analytics?.track(name: "Application Backgrounded")
9490
}
9591

9692
func applicationDidBecomeActive() {
97-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
93+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationForegrounded) == false {
9894
return
9995
}
100-
10196
analytics?.track(name: "Application Foregrounded")
10297

10398
// Lets check if we skipped application:didFinishLaunchingWithOptions,
@@ -109,11 +104,9 @@ class macOSLifecycleEvents: PlatformPlugin, macOSLifecycle {
109104
}
110105

111106
func applicationWillTerminate() {
112-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
113-
return
107+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationTerminated) == true {
108+
analytics?.track(name: "Application Terminated")
114109
}
115-
116-
analytics?.track(name: "Application Terminated")
117110
}
118111
}
119112

Sources/Segment/Plugins/Platforms/iOS/iOSLifecycleEvents.swift

+42-46
Original file line numberDiff line numberDiff line change
@@ -25,81 +25,77 @@ class iOSLifecycleEvents: PlatformPlugin, iOSLifecycle {
2525
private var didFinishLaunching = false
2626

2727
func application(_ application: UIApplication?, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
28-
2928
// Make sure we aren't double calling application:didFinishLaunchingWithOptions
3029
// by resetting the check at the start
3130
_didFinishLaunching.set(true)
32-
33-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
34-
return
35-
}
36-
31+
3732
let previousVersion: String? = UserDefaults.standard.string(forKey: Self.versionKey)
3833
let previousBuild: String? = UserDefaults.standard.string(forKey: Self.buildKey)
3934

4035
let currentVersion: String = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
4136
let currentBuild: String = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? ""
4237

4338
if previousBuild == nil {
44-
analytics?.track(name: "Application Installed", properties: [
39+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationInstalled) == true {
40+
analytics?.track(name: "Application Installed", properties: [
41+
"version": currentVersion,
42+
"build": currentBuild
43+
])
44+
}
45+
} else if let previousBuild, currentBuild != previousBuild {
46+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationUpdated) == true {
47+
analytics?.track(name: "Application Updated", properties: [
48+
"previous_version": previousVersion ?? "",
49+
"previous_build": previousBuild,
50+
"version": currentVersion,
51+
"build": currentBuild
52+
])
53+
}
54+
}
55+
56+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationOpened) == true {
57+
let sourceApp: String = launchOptions?[UIApplication.LaunchOptionsKey.sourceApplication] as? String ?? ""
58+
let url: String = launchOptions?[UIApplication.LaunchOptionsKey.url] as? String ?? ""
59+
60+
analytics?.track(name: "Application Opened", properties: [
61+
"from_background": false,
4562
"version": currentVersion,
46-
"build": currentBuild
63+
"build": currentBuild,
64+
"referring_application": sourceApp,
65+
"url": url
4766
])
48-
} else if let previousBuild,
49-
currentBuild != previousBuild {
50-
analytics?.track(name: "Application Updated", properties: [
51-
"previous_version": previousVersion ?? "",
52-
"previous_build": previousBuild,
53-
"version": currentVersion,
54-
"build": currentBuild
55-
])
5667
}
5768

58-
let sourceApp: String = launchOptions?[UIApplication.LaunchOptionsKey.sourceApplication] as? String ?? ""
59-
let url: String = launchOptions?[UIApplication.LaunchOptionsKey.url] as? String ?? ""
60-
61-
analytics?.track(name: "Application Opened", properties: [
62-
"from_background": false,
63-
"version": currentVersion,
64-
"build": currentBuild,
65-
"referring_application": sourceApp,
66-
"url": url
67-
])
68-
6969
UserDefaults.standard.setValue(currentVersion, forKey: Self.versionKey)
7070
UserDefaults.standard.setValue(currentBuild, forKey: Self.buildKey)
7171
}
7272

7373
func applicationWillEnterForeground(application: UIApplication?) {
74-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
75-
return
76-
}
77-
78-
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
79-
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
80-
81-
if didFinishLaunching == false {
82-
analytics?.track(name: "Application Opened", properties: [
83-
"from_background": true,
84-
"version": currentVersion ?? "",
85-
"build": currentBuild ?? ""
86-
])
74+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationOpened) == true {
75+
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
76+
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
77+
78+
if didFinishLaunching == false {
79+
analytics?.track(name: "Application Opened", properties: [
80+
"from_background": true,
81+
"version": currentVersion ?? "",
82+
"build": currentBuild ?? ""
83+
])
84+
}
8785
}
8886
}
8987

9088
func applicationDidEnterBackground(application: UIApplication?) {
9189
_didFinishLaunching.set(false)
92-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
93-
return
90+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationBackgrounded) == true {
91+
analytics?.track(name: "Application Backgrounded")
9492
}
95-
analytics?.track(name: "Application Backgrounded")
9693
}
9794

9895
func applicationDidBecomeActive(application: UIApplication?) {
99-
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
100-
return
96+
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationForegrounded) == true {
97+
analytics?.track(name: "Application Foregrounded")
10198
}
102-
analytics?.track(name: "Application Foregrounded")
10399
}
104100
}
105101

Sources/Segment/Startup.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extension Analytics: Subscriber {
4848
plugins += VendorSystem.current.requiredPlugins
4949

5050
// setup lifecycle if desired
51-
if configuration.values.trackApplicationLifecycleEvents, operatingMode != .synchronous {
51+
if configuration.values.trackedApplicationLifecycleEvents != .none, operatingMode != .synchronous {
5252
#if os(iOS) || os(tvOS) || os(visionOS) || os(visionOS)
5353
plugins.append(iOSLifecycleEvents())
5454
#endif

0 commit comments

Comments
 (0)