Skip to content

Instantly share code, notes, and snippets.

@sofakingforever
Last active February 14, 2019 22:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sofakingforever/e3509ceba3847f4cf13aa0769ed1dfed to your computer and use it in GitHub Desktop.
Save sofakingforever/e3509ceba3847f4cf13aa0769ed1dfed to your computer and use it in GitHub Desktop.
Writing SOLID Analytics With Kotlin for Android - Check out the UPDATED GitHub Repo: https://github.com/sofakingforever/kotlin-analytics/
package com.sofakingforever.analytics
// This code demonstrates how you could (should) decouple analytics libraries
// (or anything else) from your business logic code,
// effectively allowing you to add & remove analytics services on-the-fly.
// https://medium.com/@nadavfima/how-to-build-better-analytics-with-kotlin-60ab50ce25ac
class Analytics(private vararg val dispatchers: AnalyticsDispatcher) {
@Volatile
var isAnalyticsEnabled = true
fun trackContentView(vararg contentViews: AnalyticsContentView) {
if (!isAnalyticsEnabled) return
contentViews.forEach { event ->
dispatchers.forEach { dispatcher ->
dispatcher.trackContentView(event)
}
}
}
fun trackCustomEvent(vararg events: AnalyticsEvent) {
if (!isAnalyticsEnabled) return
events.forEach {
dispatchers.forEach { dispatcher ->
dispatcher.trackCustomEvent(it)
}
}
}
}
package com.sofakingforever.analytics
interface AnalyticsDispatcher {
fun trackContentView(contentView: AnalyticsContentView)
fun trackCustomEvent(event: AnalyticsEvent)
}
package com.sofakingforever.analytics.dispatchers
import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.ContentViewEvent
import com.crashlytics.android.answers.CustomEvent
import com.sofakingforever.analytics.AnalyticsDispatcher
import com.sofakingforever.analytics.AnalyticsContentView
import com.sofakingforever.analytics.AnalyticsEvent
class AnswersDispatcherImpl : AnalyticsDispatcher {
override fun trackCustomEvent(event: AnalyticsEvent) {
Answers.getInstance().logCustom(event.createAnswersAnalyticsEvent())
}
override fun trackContentView(contentView: AnalyticsContentView) {
Answers.getInstance().logContentView(contentView.createAnswersEvent())
}
private fun AnalyticsEvent.createAnswersAnalyticsEvent(): CustomEvent {
return CustomEvent(this.getEventName())
.apply {
this@createAnswersAnalyticsEvent.getParameters()
.forEach {
if (it.value is Number) {
putCustomAttribute(it.key, it.value as Number)
} else if (it.value is String) {
putCustomAttribute(it.key, it.value as String)
} else {
throw RuntimeException("value type " + it.value.javaClass.toString() + " is illegal")
}
}
}
}
private fun AnalyticsContentView.createAnswersEvent(): ContentViewEvent {
return ContentViewEvent().putContentName(this.getViewName())
}
}
package com.sofakingforever.analytics
interface AnalyticsContentView {
fun getViewName(): String
}
interface AnalyticsEvent {
fun getEventName(): String
fun getParameters(): MutableMap<String, Any> {
return mutableMapOf()
}
}
class ExampleApp : Application() {
lateinit var analytics: Analytics
override fun onCreate() {
analytics = Analytics(AnswersDispatcherImpl()).apply { isAnalyticsEnabled = true } // or false
analytics.trackCustomEvent(ExampleEvent());
}
}
class ExampleEvent : AnalyticsEvent {
override fun getEventName(): String = "example_event"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment