forked from openedx/openedx-app-firebase-analytics-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFirebaseAnalyticsService.swift
96 lines (75 loc) · 3.23 KB
/
FirebaseAnalyticsService.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
//
// FirebaseAnalyticsService.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 19/02/2024.
//
import Foundation
import OEXFoundation
import FirebaseAnalytics
private let MaxParameterValueCharacters = 100
private let MaxNameValueCharacters = 40
public class FirebaseAnalyticsService: AnalyticsService {
public init() {}
public func identify(id: String, username: String?, email: String?) {
Analytics.setUserID(id)
}
public func logEvent(_ event: String, parameters: [String: Any]?) {
guard let name = try? formatFirebaseName(event) else {
debugLog("Firebase: event name is not supported: \(event)")
return
}
Analytics.logEvent(name, parameters: formatParamaters(params: parameters))
}
public func logScreenEvent(_ event: String, parameters: [String: Any]?) {
logEvent(event, parameters: parameters)
}
}
public extension FirebaseAnalyticsService {
private func formatParamaters(params: [String: Any]?) -> [String: Any] {
// Firebase only supports String or Number as value for event parameters
var formattedParams: [String: Any] = [:]
for (key, value) in params ?? [:] {
if let key = try? formatFirebaseName(key) {
formattedParams[key] = formatParamValue(value: value)
}
}
return formattedParams
}
private func formatFirebaseName(_ eventName: String) throws -> String {
let trimmed = eventName.trimmingCharacters(in: .whitespaces)
do {
let regex = try NSRegularExpression(pattern: "([^a-zA-Z0-9_])", options: .caseInsensitive)
let formattedString = regex.stringByReplacingMatches(
in: trimmed,
options: .reportProgress,
range: NSRange(location: 0, length: trimmed.count),
withTemplate: "_"
)
// Resize the string to maximum 40 characters if needed
let range = NSRange(location: 0, length: min(formattedString.count, MaxNameValueCharacters))
var formattedName = NSString(string: formattedString).substring(with: range)
while formattedName.contains("__") {
formattedName = formattedName.replace(string: "__", replacement: "_")
}
return formattedName
} catch {
debugLog("Could not parse event name for Firebase.")
throw(error)
}
}
private func formatParamValue(value: Any?) -> Any? {
guard var formattedValue = value as? String else { return value}
// Firebase only supports 100 characters for parameter value
if formattedValue.count > MaxParameterValueCharacters {
let index = formattedValue.index(formattedValue.startIndex, offsetBy: MaxParameterValueCharacters)
formattedValue = String(formattedValue[..<index])
}
return formattedValue
}
}
public extension String {
func replace(string: String, replacement: String) -> String {
return replacingOccurrences(of: string, with: replacement, options: NSString.CompareOptions.literal, range: nil)
}
}