Skip to content

Instantly share code, notes, and snippets.

@getaaron
Forked from alexvbush/ObjectAnalytics.swift
Created December 15, 2017 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save getaaron/8c26a589eb09052f78670f499101bf1e to your computer and use it in GitHub Desktop.
Save getaaron/8c26a589eb09052f78670f499101bf1e to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
// this is either a third party SDK interface or your own analytics client implementation
// that actually sends JSON across the wire to deliver tracked analytics events
protocol AnalyticsClient {
func sendAnalyticsDataToTheBackend(_ eventJSON: [String: Any])
}
final class ConcreteAnalyticsClient: AnalyticsClient {
func sendAnalyticsDataToTheBackend(_ eventJSON: [String: Any]) {
print("sending event json: \(eventJSON)")
}
}
// This is the analytics interface that the rest of your app relies on
protocol AnalyticsInterface {
init(_ analyticsClient: AnalyticsClient)
func track(_ event: AnalyticsEvent)
}
// this is a concrete implementation of analytics that is used by your app
final class Analytics: AnalyticsInterface {
private let analyticsClient: AnalyticsClient
required init(_ analyticsClient: AnalyticsClient) {
self.analyticsClient = analyticsClient
}
func track(_ event: AnalyticsEvent) {
var dict = event.asDictionary()
for pair in dict where pair.value == "" {
dict.removeValue(forKey: pair.key)
}
print("tracking event \(dict)")
// here it suppose to use the injected analyitcs client actually issue a request to send over the JSON of the tracked event
analyticsClient.sendAnalyticsDataToTheBackend(dict)
}
}
// this is a generic event that can be used for various kind of event tracking across your app
class AnalyticsEvent {
let eventName: String
var uiElement: String?
var screen: String?
init(_ eventName: String, uiElement: String? = nil, screen: String? = nil) {
self.eventName = eventName
self.uiElement = uiElement
self.screen = screen
}
func asDictionary() -> [String: String] {
return [
"event_name": eventName,
"screen": screen ?? "",
"element": uiElement ?? ""
]
}
}
// this is a case specific event that is crafted only for tracking login
class LoginAnalyticsEvent: AnalyticsEvent {
let loggedInUserId: Int
init(loggedInUserId: Int) {
self.loggedInUserId = loggedInUserId
super.init("User Logged In", uiElement: nil, screen: nil)
}
override func asDictionary() -> [String : String] {
let eventDictionary = super.asDictionary()
var fullDictionary = [
"user_id": String(loggedInUserId)
]
fullDictionary.merge(eventDictionary) { (newDictionaryValue, _) -> String in return newDictionaryValue }
return fullDictionary
}
}
// This is how you'd use analytics and events across your codebase
let analyticsClient = ConcreteAnalyticsClient()
let analytics = Analytics(analyticsClient)
var buttonTappedEvent = AnalyticsEvent("Tapped")
buttonTappedEvent.screen = "My Awesome Screen"
analytics.track(buttonTappedEvent)
let loginEvent = LoginAnalyticsEvent(loggedInUserId: 3)
analytics.track(loginEvent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment