Skip to content

feat: Allow for more granular tracked lifecycle events to track #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Examples/apps/BasicExample/BasicExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Override point for customization after application launch.

let configuration = Configuration(writeKey: "WRITE KEY")
.trackApplicationLifecycleEvents(true)
.setTrackedApplicationLifecycleEvents(.all)
.flushInterval(10)
.flushAt(2)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Override point for customization after application launch.

let configuration = Configuration(writeKey: "EioRQCqLHUECnoSseEguI8GnxOlZTOyX")
.trackApplicationLifecycleEvents(true)
.setTrackedApplicationLifecycleEvents(.all)
.flushInterval(1)

analytics = Analytics(configuration: configuration)
Expand Down
2 changes: 1 addition & 1 deletion Examples/apps/MacExample/MacExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// Insert code here to initialize your application

let configuration = Configuration(writeKey: "<WRITE KEY>")
.trackApplicationLifecycleEvents(true)
.setTrackedApplicationLifecycleEvents(.all)
.flushInterval(10)
.flushAt(1)
.errorHandler { error in
Expand Down
2 changes: 1 addition & 1 deletion Examples/apps/ObjCExample/ObjCExample/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ @implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
SEGConfiguration *config = [[SEGConfiguration alloc] initWithWriteKey:@"<WRITE KEY>"];
config.trackApplicationLifecycleEvents = YES;
config.trackApplicationLifecycleEvents = SEGTrackedLifecycleEvent.all;
config.flushAt = 1;

_analytics = [[SEGAnalytics alloc] initWithConfiguration: config];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,5 @@ extension Analytics {
static var main = Analytics(configuration:
Configuration(writeKey: "ABCD")
.flushAt(3)
.trackApplicationLifecycleEvents(true))
.setTrackedApplicationLifecycleEvents(.all))
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ extension Analytics {
static var main = Analytics(configuration:
Configuration(writeKey: "ABCD")
.flushAt(3)
.trackApplicationLifecycleEvents(true))
.setTrackedApplicationLifecycleEvents(.all))
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ExtensionDelegate: NSObject, WKExtensionDelegate {
func applicationDidFinishLaunching() {
// Perform any final initialization of your application.
let configuration = Configuration(writeKey: "WRITE KEY")
.trackApplicationLifecycleEvents(true)
.setTrackedApplicationLifecycleEvents(.all)
.flushInterval(10)

analytics = Analytics(configuration: configuration)
Expand Down
6 changes: 3 additions & 3 deletions Examples/tasks/MultiInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ import Segment
extension Analytics {
static var main = Analytics(configuration: Configuration(writeKey: "1234")
.flushAt(3)
.trackApplicationLifecycleEvents(true))
.setTrackedApplicationLifecycleEvents(.all))

static var support = Analytics(configuration: Configuration(writeKey: "5678")
.flushAt(10)
.trackApplicationLifecycleEvents(false))
.setTrackedApplicationLifecycleEvents(.none))
}
65 changes: 63 additions & 2 deletions Sources/Segment/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,61 @@ public enum StorageMode {

// MARK: - Internal Configuration

@objc(SEGTrackedLifecycleEvent)
public final class TrackedLifecycleEvent: NSObject, OptionSet {
public let rawValue: Int

public init(rawValue: Int) {
self.rawValue = rawValue
}

public override func isEqual(_ object: Any?) -> Bool {
(object as? Self)?.rawValue == rawValue
}

public override var hash: Int {
rawValue.hashValue
}

@objc public static let none: TrackedLifecycleEvent = []
@objc public static let applicationInstalled = TrackedLifecycleEvent(rawValue: 1 << 0)
@objc public static let applicationUpdated = TrackedLifecycleEvent(rawValue: 1 << 1)
@objc public static let applicationOpened = TrackedLifecycleEvent(rawValue: 1 << 2)
@objc public static let applicationBackgrounded = TrackedLifecycleEvent(rawValue: 1 << 3)
@objc public static let applicationForegrounded = TrackedLifecycleEvent(rawValue: 1 << 4)
#if os(macOS)
@objc public static let applicationUnhidden = TrackedLifecycleEvent(rawValue: 1 << 5)
@objc public static let applicationHidden = TrackedLifecycleEvent(rawValue: 1 << 6)
@objc public static let applicationTerminated = TrackedLifecycleEvent(rawValue: 1 << 7)

@objc public static let all: TrackedLifecycleEvent = [
.applicationInstalled,
.applicationUpdated,
.applicationOpened,
.applicationBackgrounded,
.applicationForegrounded,
.applicationUnhidden,
.applicationHidden,
.applicationTerminated,
]
#elseif os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst)
@objc public static let all: TrackedLifecycleEvent = [
.applicationInstalled,
.applicationUpdated,
.applicationOpened,
.applicationBackgrounded,
.applicationForegrounded,
]
#else
@objc public static let all = TrackedLifecycleEvent.none
#endif
}

public class Configuration {
internal struct Values {
var writeKey: String
var application: Any? = nil
var trackApplicationLifecycleEvents: Bool = true
var trackedApplicationLifecycleEvents = TrackedLifecycleEvent.all
var flushAt: Int = 20
var flushInterval: TimeInterval = 30
var defaultSettings: Settings? = nil
Expand Down Expand Up @@ -110,8 +160,19 @@ public extension Configuration {
/// - Parameter enabled: A bool value
/// - Returns: The current Configuration.
@discardableResult
@available(*, deprecated, message: "Use `setTrackedApplicationLifecycleEvents(_:)` for more granular control")
func trackApplicationLifecycleEvents(_ enabled: Bool) -> Configuration {
values.trackApplicationLifecycleEvents = enabled
values.trackedApplicationLifecycleEvents = enabled ? .all : .none
return self
}

/// Opt-in/out of tracking lifecycle events. The default value is `.none`.
///
/// - Parameter events: An option set of the events to track.
/// - Returns: The current Configuration.
@discardableResult
func setTrackedApplicationLifecycleEvents(_ events: TrackedLifecycleEvent) -> Configuration {
values.trackedApplicationLifecycleEvents = events
return self
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Segment/ObjC/ObjCConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public class ObjCConfiguration: NSObject {

/// Opt-in/out of tracking lifecycle events. The default value is `false`.
@objc
public var trackApplicationLifecycleEvents: Bool {
public var trackApplicationLifecycleEvents: TrackedLifecycleEvent {
get {
return configuration.values.trackApplicationLifecycleEvents
return configuration.values.trackedApplicationLifecycleEvents
}
set(value) {
configuration.trackApplicationLifecycleEvents(value)
configuration.setTrackedApplicationLifecycleEvents(value)
}
}

Expand Down
79 changes: 36 additions & 43 deletions Sources/Segment/Plugins/Platforms/Mac/macOSLifecycleEvents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ class macOSLifecycleEvents: PlatformPlugin, macOSLifecycle {
// Make sure we aren't double calling application:didFinishLaunchingWithOptions
// by resetting the check at the start
_didFinishLaunching.set(true)

if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
return
}

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

if previousBuild == nil {
analytics?.track(name: "Application Installed", properties: [
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationInstalled) == true {
analytics?.track(name: "Application Installed", properties: [
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
}
} else if currentBuild != previousBuild {
analytics?.track(name: "Application Updated", properties: [
"previous_version": previousVersion ?? "",
"previous_build": previousBuild ?? "",
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationUpdated) == true {
analytics?.track(name: "Application Updated", properties: [
"previous_version": previousVersion ?? "",
"previous_build": previousBuild ?? "",
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
}
}

if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationOpened) == true {
analytics?.track(name: "Application Opened", properties: [
"from_background": false,
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
}

analytics?.track(name: "Application Opened", properties: [
"from_background": false,
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])


UserDefaults.standard.setValue(currentVersion, forKey: Self.versionKey)
UserDefaults.standard.setValue(currentBuild, forKey: Self.buildKey)
}

func applicationDidUnhide() {
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
return
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationUnhidden) == true {
let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String

analytics?.track(name: "Application Unhidden", properties: [
"from_background": true,
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
}

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

analytics?.track(name: "Application Unhidden", properties: [
"from_background": true,
"version": currentVersion ?? "",
"build": currentBuild ?? ""
])
}

func applicationDidHide() {
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
return
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationHidden) == true {
analytics?.track(name: "Application Hidden")
}

analytics?.track(name: "Application Hidden")
}
func applicationDidResignActive() {
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
return
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationBackgrounded) == true {
analytics?.track(name: "Application Backgrounded")
}

analytics?.track(name: "Application Backgrounded")
}

func applicationDidBecomeActive() {
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationForegrounded) == false {
return
}

analytics?.track(name: "Application Foregrounded")

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

func applicationWillTerminate() {
if analytics?.configuration.values.trackApplicationLifecycleEvents == false {
return
if analytics?.configuration.values.trackedApplicationLifecycleEvents.contains(.applicationTerminated) == true {
analytics?.track(name: "Application Terminated")
}

analytics?.track(name: "Application Terminated")
}
}

Expand Down
Loading