Skip to content

Commit 5b95b74

Browse files
zhu-xiaoweixiaoweii
andauthored
feat: add preset events. (#2)
--------- Co-authored-by: xiaoweii <xiaoweii@amazom.com>
1 parent abe9e8f commit 5b95b74

39 files changed

+1247
-511
lines changed

Package.resolved

Lines changed: 17 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ let package = Package(
1414
)
1515
],
1616
dependencies: [
17-
.package(url: "https://github.com/aws-amplify/amplify-swift.git", exact: "2.4.0"),
17+
.package(url: "https://github.com/aws-amplify/amplify-swift.git", exact: "2.10.0"),
1818
.package(url: "https://github.com/stephencelis/SQLite.swift.git", exact: "0.13.2"),
1919
.package(url: "https://github.com/1024jp/GzipSwift", exact: "5.2.0"),
2020
.package(url: "https://github.com/httpswift/swifter", exact: "1.5.0")

Sources/Clickstream/AWSClickstreamPlugin+ClientBehavior.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,29 @@ import Foundation
1010

1111
public extension AWSClickstreamPlugin {
1212
func identifyUser(userId: String, userProfile: AnalyticsUserProfile?) {
13-
Task {
14-
if userId == Event.User.USER_ID_NIL {
15-
await analyticsClient.removeUserAttribute(forKey: Event.ReservedAttribute.USER_ID)
16-
} else if userId != Event.User.USER_ID_EMPTY {
17-
await analyticsClient.addUserAttribute(userId, forKey: Event.ReservedAttribute.USER_ID)
13+
if userId == Event.User.USER_ID_EMPTY {
14+
userProfile?.properties?.forEach { key, value in
15+
Task {
16+
await analyticsClient.addUserAttribute(value, forKey: key)
17+
}
1818
}
19-
}
20-
userProfile?.properties?.forEach { key, value in
19+
} else {
2120
Task {
22-
await analyticsClient.addUserAttribute(value, forKey: key)
21+
if userId == Event.User.USER_ID_NIL {
22+
await analyticsClient.updateUserId(nil)
23+
} else {
24+
await analyticsClient.updateUserId(userId)
25+
}
2326
}
2427
}
28+
Task {
29+
await analyticsClient.updateUserAttributes()
30+
}
31+
record(eventWithName: Event.PresetEvent.PROFILE_SET)
2532
}
2633

2734
func record(event: AnalyticsEvent) {
28-
guard let event = event as? BaseClickstreamEvent else{
35+
guard let event = event as? BaseClickstreamEvent else {
2936
log.error("Event type does not match")
3037
return
3138
}
@@ -83,8 +90,8 @@ public extension AWSClickstreamPlugin {
8390
}
8491
}
8592

86-
func getEscapeHatch() -> ClickstreamContextConfiguration {
87-
clickstream.configuration
93+
func getEscapeHatch() -> ClickstreamContext {
94+
clickstream
8895
}
8996

9097
func enable() {

Sources/Clickstream/AWSClickstreamPlugin+Configure.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import Amplify
99
import Foundation
1010
import Network
11+
#if canImport(UIKit)
12+
import UIKit
13+
#endif
1114

1215
public extension AWSClickstreamPlugin {
1316
/// called when sdk init.
@@ -32,22 +35,19 @@ public extension AWSClickstreamPlugin {
3235
isCompressEvents: configuration.isCompressEvents)
3336
clickstream = try ClickstreamContext(with: contextConfiguration)
3437

35-
let sessionClient = SessionClient(configuration: .init(uniqueDeviceId: clickstream.uniqueId,
36-
sessionBackgroundTimeout: TimeInterval(10)),
37-
userDefaults: clickstream.storage.userDefaults)
38+
let sessionClient = SessionClient(clickstream: clickstream)
3839
clickstream.sessionClient = sessionClient
39-
let sessionProvider: () -> Session = { [weak sessionClient] in
40+
let sessionProvider: () -> Session? = { [weak sessionClient] in
4041
guard let sessionClient else {
4142
fatalError("SessionClient was deallocated")
4243
}
43-
return sessionClient.currentSession
44+
return sessionClient.getCurrentSession()
4445
}
4546
let eventRecorder = try EventRecorder(clickstream: clickstream)
4647
analyticsClient = try AnalyticsClient(clickstream: clickstream,
4748
eventRecorder: eventRecorder,
4849
sessionProvider: sessionProvider)
4950
clickstream.analyticsClient = analyticsClient
50-
sessionClient.analyticsClient = analyticsClient
5151
let networkMonitor = NWPathMonitor()
5252
clickstream.networkMonitor = networkMonitor
5353

@@ -57,7 +57,6 @@ public extension AWSClickstreamPlugin {
5757
autoFlushEventsTimer = RepeatingTimer.createRepeatingTimer(
5858
timeInterval: timeInterval,
5959
eventHandler: { [weak self] in
60-
self?.log.debug("AutoFlushTimer triggered, flushing events")
6160
self?.flushEvents()
6261
}
6362
)
@@ -67,7 +66,6 @@ public extension AWSClickstreamPlugin {
6766
autoFlushEventsTimer: autoFlushEventsTimer,
6867
networkMonitor: networkMonitor
6968
)
70-
sessionClient.startSession()
7169
log.debug("init the sdk success")
7270
}
7371

@@ -84,7 +82,7 @@ public extension AWSClickstreamPlugin {
8482
self.networkMonitor = networkMonitor
8583
self.networkMonitor.startMonitoring(
8684
using: DispatchQueue(
87-
label: "com.amazonaws.solution.clickstream.AnalyticsPlugin.NetworkMonitor"
85+
label: "software.aws.solution.clickstream.AnalyticsPlugin.NetworkMonitor"
8886
)
8987
)
9088
}

Sources/Clickstream/AWSClickstreamPlugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Amplify
99
import Foundation
1010

1111
public final class AWSClickstreamPlugin: AnalyticsCategoryPlugin {
12-
var clickstream: ClickstreamContext!
12+
public var clickstream: ClickstreamContext!
1313

1414
/// Automatically flushes the events that have been recorded on an interval
1515
var autoFlushEventsTimer: DispatchSourceTimer?

Sources/Clickstream/ClickstreamAnalytics.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ public enum ClickstreamAnalytics {
4545

4646
/// Add user attributes
4747
/// - Parameter attributes: the user attributes to add
48-
public static func addUserAttributes(userAttributes: ClickstreamUserAttribute) {
49-
let userId: String = userAttributes.userId ?? Event.User.USER_ID_EMPTY
50-
let userProfile = AnalyticsUserProfile(location: nil, properties: userAttributes.attribute)
51-
Amplify.Analytics.identifyUser(userId: userId,
48+
public static func addUserAttributes(attributes: ClickstreamAttribute) {
49+
let userProfile = AnalyticsUserProfile(location: nil, properties: attributes)
50+
Amplify.Analytics.identifyUser(userId: Event.User.USER_ID_EMPTY,
5251
userProfile: userProfile)
5352
}
5453

@@ -66,6 +65,6 @@ public enum ClickstreamAnalytics {
6665
/// - Returns: ClickstreamContextConfiguration: current userId, nil for logout
6766
public static func getClickStreamConfiguration() throws -> ClickstreamContextConfiguration? {
6867
let plugin = try Amplify.Analytics.getPlugin(for: "awsClickstreamPlugin")
69-
return (plugin as? AWSClickstreamPlugin)?.getEscapeHatch()
68+
return (plugin as? AWSClickstreamPlugin)?.getEscapeHatch().configuration
7069
}
7170
}

Sources/Clickstream/ClickstreamAttribute.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Amplify
99

1010
public typealias ClickstreamAttribute = AnalyticsProperties
1111
public typealias AttributeValue = AnalyticsPropertyValue
12+
extension Int64: AnalyticsPropertyValue {}
1213

1314
public struct BaseClickstreamEvent: AnalyticsEvent {
1415
public var properties: AnalyticsProperties?
@@ -32,10 +33,8 @@ public struct BaseClickstreamEvent: AnalyticsEvent {
3233
}
3334

3435
public struct ClickstreamUserAttribute {
35-
public var userId: String?
3636
public var attribute: ClickstreamAttribute?
37-
public init(userId: String?, attribute: ClickstreamAttribute?) {
38-
self.userId = userId
37+
public init(attribute: ClickstreamAttribute?) {
3938
self.attribute = attribute
4039
}
4140
}

Sources/Clickstream/Dependency/Clickstream/ActivityTracking/ActivityTracker.swift

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ enum ActivityEvent {
1717
case applicationDidMoveToBackground
1818
case applicationWillMoveToForeground
1919
case applicationWillTerminate
20-
case backgroundTrackingDidTimeout
2120
}
2221

2322
enum ApplicationState {
2423
case initializing
2524
case runningInForeground
26-
case runningInBackground(isStale: Bool)
25+
case runningInBackground
2726
case terminated
2827

2928
enum Resolver {
@@ -37,11 +36,9 @@ enum ApplicationState {
3736
case .applicationWillTerminate:
3837
return .terminated
3938
case .applicationDidMoveToBackground:
40-
return .runningInBackground(isStale: false)
39+
return .runningInBackground
4140
case .applicationWillMoveToForeground:
4241
return .runningInForeground
43-
case .backgroundTrackingDidTimeout:
44-
return .runningInBackground(isStale: true)
4542
}
4643
}
4744
}
@@ -56,17 +53,6 @@ protocol ActivityTrackerBehaviour {
5653
}
5754

5855
class ActivityTracker: ActivityTrackerBehaviour {
59-
#if canImport(UIKit)
60-
private var backgroundTask: UIBackgroundTaskIdentifier = .invalid
61-
#endif
62-
63-
private var backgroundTimer: Timer? {
64-
willSet {
65-
backgroundTimer?.invalidate()
66-
}
67-
}
68-
69-
private let backgroundTrackingTimeout: TimeInterval
7056
private let stateMachine: StateMachine<ApplicationState, ActivityEvent>
7157
private var stateMachineSubscriberToken: StateMachineSubscriberToken?
7258

@@ -100,10 +86,7 @@ class ActivityTracker: ActivityTrackerBehaviour {
10086
applicationWillTerminate
10187
]
10288

103-
init(backgroundTrackingTimeout: TimeInterval,
104-
stateMachine: StateMachine<ApplicationState, ActivityEvent>? = nil)
105-
{
106-
self.backgroundTrackingTimeout = backgroundTrackingTimeout
89+
init(stateMachine: StateMachine<ApplicationState, ActivityEvent>? = nil) {
10790
self.stateMachine = stateMachine ??
10891
StateMachine(initialState: .initializing,
10992
resolver: ApplicationState.Resolver.resolve(currentState:event:))
@@ -128,44 +111,11 @@ class ActivityTracker: ActivityTrackerBehaviour {
128111
stateMachineSubscriberToken = stateMachine.subscribe(listener)
129112
}
130113

131-
private func beginBackgroundTracking() {
132-
#if canImport(UIKit)
133-
if backgroundTrackingTimeout > 0 {
134-
backgroundTask = UIApplication.shared.beginBackgroundTask(withName:
135-
Constants.backgroundTask)
136-
{ [weak self] in
137-
self?.stateMachine.process(.backgroundTrackingDidTimeout)
138-
self?.stopBackgroundTracking()
139-
}
140-
}
141-
#endif
142-
guard backgroundTrackingTimeout != .infinity else { return }
143-
backgroundTimer = Timer.scheduledTimer(withTimeInterval:
144-
backgroundTrackingTimeout, repeats: false)
145-
{ [weak self] _ in
146-
self?.stateMachine.process(.backgroundTrackingDidTimeout)
147-
self?.stopBackgroundTracking()
148-
}
149-
}
150-
151-
private func stopBackgroundTracking() {
152-
backgroundTimer = nil
153-
#if canImport(UIKit)
154-
guard backgroundTask != .invalid else {
155-
return
156-
}
157-
UIApplication.shared.endBackgroundTask(backgroundTask)
158-
backgroundTask = .invalid
159-
#endif
160-
}
161-
162114
@objc private func handleApplicationStateChange(_ notification: Notification) {
163115
switch notification.name {
164116
case Self.applicationDidMoveToBackground:
165-
beginBackgroundTracking()
166117
stateMachine.process(.applicationDidMoveToBackground)
167118
case Self.applicationWillMoveToForegound:
168-
stopBackgroundTracking()
169119
stateMachine.process(.applicationWillMoveToForeground)
170120
case Self.applicationWillTerminate:
171121
stateMachine.process(.applicationWillTerminate)
@@ -174,11 +124,3 @@ class ActivityTracker: ActivityTrackerBehaviour {
174124
}
175125
}
176126
}
177-
178-
#if canImport(UIKit)
179-
extension ActivityTracker {
180-
enum Constants {
181-
static let backgroundTask = "com.amazonaws.solution.clickstream.SessionBackgroundTask"
182-
}
183-
}
184-
#endif

Sources/Clickstream/Dependency/Clickstream/ActivityTracking/StateMachine.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension AnyCancellable: StateMachineSubscriberToken {}
1616
class StateMachine<State, Event> {
1717
typealias Reducer = (State, Event) -> State
1818
private let queue = DispatchQueue(
19-
label: "com.amazonaws.solution.Clickstream.StateMachine<\(State.self), \(Event.self)>",
19+
label: "software.aws.solution.Clickstream.StateMachine<\(State.self), \(Event.self)>",
2020
target: DispatchQueue.global())
2121
private var reducer: Reducer
2222
#if canImport(Combine)
@@ -37,9 +37,7 @@ class StateMachine<State, Event> {
3737

3838
func process(_ event: Event) {
3939
queue.sync {
40-
log.info("Processing event \(event) for current state \(self.state)")
4140
let newState = self.reducer(self.state, event)
42-
log.info("New state: \(newState)")
4341
self.state = newState
4442
}
4543
}

0 commit comments

Comments
 (0)