Last active
January 31, 2024 19:11
-
-
Save astrokin/ffa8d9aa92a23a76150f414fffa249d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension AnalyticsEvent: TrackingEvent { | |
var trackingName: String { | |
MirroringHelper.name(from: self) | |
} | |
var trackingAttributes: [String: String] { | |
MirroringHelper.attributes(from: self) | |
} | |
} | |
public protocol TrackingEvent { | |
var trackingName: String { get } | |
var trackingAttributes: [String: String] { get } | |
} | |
public enum TrackingPolicy { | |
case multipleTracking | |
case trackOnce | |
} | |
public protocol AnalyticsService { | |
func track(event: TrackingEvent, trackingPolicy: TrackingPolicy) | |
func track(userProperties: [String: Any]) | |
} | |
public enum MirroringHelper { | |
public static func reflection(on obj: Any) -> [String: String] { | |
let reflection = Mirror(reflecting: obj) | |
guard reflection.displayStyle == .enum, | |
let associated = reflection.children.first | |
else { | |
return [:] | |
} | |
let values = Mirror(reflecting: associated.value).children | |
var valuesArray = [String: String]() | |
for case let item in values where item.label != nil { | |
// swiftlint:disable:next force_unwrapping | |
valuesArray[item.label!] = String(describing: item.value) | |
} | |
let result = Dictionary(uniqueKeysWithValues: valuesArray.filter { $0.value != "nil" }.map { ($0.key, unwrapped($0.value)) }) | |
return result | |
} | |
public static func name(from obj: Any) -> String { | |
let mirror = Mirror(reflecting: obj) | |
if let label = mirror.children.first?.label { | |
return label | |
} else { | |
return String(describing: obj) | |
} | |
} | |
public static func attributes(from obj: Any) -> [String: String] { | |
var result = MirroringHelper.reflection(on: obj) | |
let name = name(from: obj) | |
counted(name: name, attributes: &result) | |
return result | |
} | |
public static func counted(name: String, attributes: inout [String: String]) { | |
var count = Foundation.UserDefaults.standard.integer(forKey: name) | |
count += 1 | |
Foundation.UserDefaults.standard.set(count, forKey: name) | |
attributes["count"] = "\(count)" | |
} | |
private static func unwrapped(_ value: String) -> String { | |
guard value.starts(with: "Optional(") else { | |
return value | |
} | |
return String(value.replacingOccurrences(of: "Optional(", with: "").dropLast().replacingOccurrences(of: "\"", with: "")) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment