/
Timeline.swift
137 lines (118 loc) · 4.2 KB
/
Timeline.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// Timeline.swift
//
//
// Created by Marvin Liu on 10/27/22.
//
import Foundation
public class Timeline {
var amplitude: Amplitude?
internal let plugins: [PluginType: Mediator]
var sessionId: Int64 = -1
var lastEventId: Int64 = 0
var lastEventTime: Int64 = -1
init() {
self.plugins = [
PluginType.before: Mediator(),
PluginType.enrichment: Mediator(),
PluginType.destination: Mediator(),
PluginType.utility: Mediator(),
]
}
func start() {
sessionId = amplitude?.storage.read(key: .PREVIOUS_SESSION_ID) ?? -1
lastEventId = amplitude?.storage.read(key: .LAST_EVENT_ID) ?? -1
lastEventTime = amplitude?.storage.read(key: .LAST_EVENT_TIME) ?? -1
}
func process(event: BaseEvent) {
let eventTimeStamp = event.timestamp!
var skipEvent: Bool = false
var sessionEvents: [BaseEvent]?
if event.eventType == Constants.AMP_SESSION_START_EVENT {
if event.sessionId! < 0 {
skipEvent = true
sessionEvents = self.amplitude?.startOrContinueSession(timestamp: eventTimeStamp)
} else {
_ = self.amplitude?.setSessionId(sessionId: eventTimeStamp)
self.amplitude?.refreshSessionTime(timestamp: eventTimeStamp)
}
} else if event.eventType == Constants.AMP_SESSION_END_EVENT {
// do nothing
} else {
if !(self.amplitude?._inForeground ?? false) {
sessionEvents = self.amplitude?.startOrContinueSession(timestamp: eventTimeStamp)
} else {
_ = self.amplitude?.refreshSessionTime(timestamp: eventTimeStamp)
}
}
if !skipEvent && event.sessionId! < 0 {
event.sessionId = sessionId
}
let savedLastEventId = lastEventId
sessionEvents?.forEach({ sessionEvent in
if sessionEvent.eventId == nil {
let newEventId = lastEventId + 1
sessionEvent.eventId = newEventId
lastEventId = newEventId
}
})
if !skipEvent {
let newEventId = lastEventId + 1
event.eventId = newEventId
lastEventId = newEventId
}
if lastEventId > savedLastEventId {
do {
_ = try? self.amplitude?.storage.write(key: .LAST_EVENT_ID, value: lastEventId)
}
}
sessionEvents?.forEach({ sessionEvent in
self.processEvent(event: sessionEvent)
})
if !skipEvent {
processEvent(event: event)
}
}
func processEvent(event: BaseEvent) {
let beforeResult = self.applyPlugin(pluginType: PluginType.before, event: event)
let enrichmentResult = self.applyPlugin(pluginType: PluginType.enrichment, event: beforeResult)
_ = self.applyPlugin(pluginType: PluginType.destination, event: enrichmentResult)
}
internal func applyPlugin(pluginType: PluginType, event: BaseEvent?) -> BaseEvent? {
var result: BaseEvent? = event
if let mediator = plugins[pluginType] {
result = mediator.execute(event: event!)
}
return result
}
internal func add(plugin: Plugin) {
if let mediator = plugins[plugin.type] {
mediator.add(plugin: plugin)
}
}
internal func remove(plugin: Plugin) {
// remove all plugins with this name in every category
for _plugin in plugins {
let list = _plugin.value
list.remove(plugin: plugin)
}
}
internal func applyClosure(_ closure: (Plugin) -> Void) {
for plugin in plugins {
let mediator = plugin.value
mediator.applyClosure(closure)
}
}
internal func apply(_ closure: (Plugin) -> Void) {
for type in PluginType.allCases {
if let mediator = plugins[type] {
mediator.plugins.forEach { (plugin) in
closure(plugin)
if let destPlugin = plugin as? DestinationPlugin {
destPlugin.apply(closure: closure)
}
}
}
}
}
}