Declarative analytics: gAnalytics

About Analytics in Apps

ServiceLocator.getInstance().getAnalytics().track(CATEGORY, "some_string");
public static void track(String action) {
ServiceLocator.getInstance().getAnalytics().track(CATEGORY, action);
}
public static void track(String action, String label) {
analytics.track(CATEGORY, action, label);
}
public static void track(String category, String action, String label) {
tracker.send(HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label)
.build());
}

Declarative solution (Proxy approach)

@HasPrefix(splitter = "_")
interface AnalyticsCandyShop {
fun near()
fun opened()
fun closed()
fun sell()
}
interface AnalyticsWrapper {
fun <T : Any> create(kClass: KClass<T>) = create(kClass.java)
fun <T : Any> create(clazz: Class<T>): T
}

class AnalyticsSingleWrapper : AnalyticsWrapper {
@Suppress("unchecked_cast")
override fun <T : Any> create(clazz: Class<T>): T {
return Proxy.newProxyInstance(clazz.classLoader, arrayOf<Class<*>>(clazz)) { proxy, method, args ->
//do processing annotations, making conversions
//or
//some other work !HERE!
} as T
}
}
interface EventProvider {
fun provide(event: Event)
}
class AnalyticsSingleWrapper(private val eventProvider: EventProvider) : AnalyticsWrapper {
@Suppress("unchecked_cast")
override fun <T : Any> create(clazz: Class<T>): T {
return Proxy.newProxyInstance(clazz.classLoader, arrayOf<Class<*>>(clazz)) { proxy, method, args ->
//build here category, action, label and value
val event = Event(category, action, label, value)
eventProvider.provide(event)
} as T
}

Annotations

@Category (Scope: Class)

@Action (Scope: Method)

@Label (Scope: Parameter)

@HasPrefix (Scope: Class/Method)

@HasPrefix
interface CandyShop() {
fun opened()
}
@HasPrefix(name = "cs", splitter = "_-_")
interface CandyShop() {
fun opened()
}

@NoPrefix (Scope: Class/Method)

@HasPrefix
interface SomeCategory {
fun action1()
@NoPrefix fun action2()
}

Default behaviour

Future

Conclusion

--

--

--

Love being creative to solve some problems with an simple and elegant ways

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

New Guide:👏Track your coverage statistics with SonarQube and Buddy!

Spring Boot & MongoDB

Creator of PhaserQuest Joins Aavegotchi as Senior Game Programmer

Eloquent polymorphic relationships explained (with examples)

Simple tip to read code faster

Python Dict Comprehension

How to scrape HREF in BeautifulSoup Using Python

scrape HREF in BeautifulSoup

Difference between HTTP1.1 vs HTTP2

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Michael Spitsin

Michael Spitsin

Love being creative to solve some problems with an simple and elegant ways

More from Medium

Perimeter Security

How Zerocode helped testing Disaster Recovery Solution for AWS MSK ?

Mocking GCP DatastoreRepository::performTransaction with MockK

Post-compile AOP with AspectJ and Gradle - practical guide