59 lines
1.6 KiB
Swift
59 lines
1.6 KiB
Swift
import Combine
|
|
import Foundation
|
|
|
|
protocol AnalyticsTracking {
|
|
func track(_ event: String, attributes: [String: String])
|
|
}
|
|
|
|
struct HermesTrackedEvent: Identifiable, Equatable {
|
|
let id = UUID()
|
|
let event: String
|
|
let attributes: [String: String]
|
|
let timestamp: Date
|
|
}
|
|
|
|
@MainActor
|
|
final class HermesAnalyticsClient: ObservableObject, AnalyticsTracking {
|
|
@Published private(set) var trackedEvents: [HermesTrackedEvent] = []
|
|
|
|
func track(_ event: String, attributes: [String: String]) {
|
|
trackedEvents.append(
|
|
HermesTrackedEvent(
|
|
event: event,
|
|
attributes: attributes,
|
|
timestamp: Date()
|
|
)
|
|
)
|
|
}
|
|
|
|
func flush(using repository: HermesRepository) async {
|
|
guard repository.currentSession != nil else {
|
|
return
|
|
}
|
|
|
|
let pendingEvents = trackedEvents
|
|
guard !pendingEvents.isEmpty else {
|
|
return
|
|
}
|
|
|
|
do {
|
|
try await repository.submitAnalyticsBatch(
|
|
HermesAnalyticsBatchRequest(
|
|
events: pendingEvents.map { event in
|
|
HermesAnalyticsEventInput(
|
|
eventName: event.event,
|
|
occurredAt: event.timestamp,
|
|
attributes: event.attributes.map { HermesAnalyticsAttributeInput(key: $0.key, value: $0.value) }
|
|
)
|
|
}
|
|
)
|
|
)
|
|
|
|
let deliveredIds = Set(pendingEvents.map(\.id))
|
|
trackedEvents.removeAll { deliveredIds.contains($0.id) }
|
|
} catch {
|
|
return
|
|
}
|
|
}
|
|
}
|