-
-
Save getaaron/8c26a589eb09052f78670f499101bf1e to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//: 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