metrica_generator

A Flutter plugin to generate AppMetrica actions.

In a large project lots of actions reported to AppMetrica Analytics can be hard to manage and standardize. Developers have to produce tons of boilerplate code while retaining the proper events' nested structure. metrica_generator is a tool separating concerns here and taking over all of the boilerplate.

Getting Started

Add the dependency

# pubspec.yaml
dependencies:
  metrica_generator: ^0.0.1

Create Your events and types

In a separate folder create events.yaml. Fill it with the events you will be using. If needed, specify custom types in the types.yaml in the same directory. Here is a commented example to follow:

# events.yaml

# Set the nesting, name of the event, and the object it should send
- path: actions/main-page
  name: EntryCreated
  obj: Entry

# To specify a list use [list of ...] notation
- path: actions/users-page/modal
  name: UsersSelected
  obj: list of User

# To specify an optional value use [opt of ...]
- path: results
  name: Points
  obj: opt of list of double

This would generate events in Dart:

void reportEntryCreated(Entry object) => _reporter.reportEventWithMap(
    "actions",
    {
        "main-page" : object.toJson
    },
);
void reportUsersSelected(List<User> object) => _reporter.reportEventWithMap(
    "actions",
    {
        "users-page" : {
        "modal" : object.toJson
        }
    },
);
void reportPoints(List<double>? object) => _reporter.reportEventWithMap(
    "results", object.toJson,
);

However, currently nothing would compile, since we haven't added custom types.

# types.yaml

# For a custom entity specify name, JSON representation, and its variables 
- name: Entry
  repr: "$id: $name called $selectedNames"
  vars:
    - name: id
      type: int
    - name: name
      type: str
    - name: selectedNames
      type: list of Name

# Skip the User model
...

# Name model will not have a custom representation function
- name: Name
  vars:
    - name: name
      type: opt of str
    - name: middleName
      type: opt of str
    - name: lastName
      type: opt of str

So in Dart we'll get:

class Entry {
  final int id;
  final String name;
  final List<Name> selectedNames;
  const Entry({
    required this.id,
    required this.name,
    required this.selectedNames,
  });
  // Custom representation is used to build a string following the pattern from 
  // the yaml
  Object get toJson => "${id.toJson}: ${name.toJson} called $selectedNames";
}
...
class Name {
  final String? name;
  final String? middleName;
  final String? lastName;
  // Optional variables will not be required 
  const Name({
    this.name,
    this.middleName,
    this.lastName,
  });
  Object get toJson => {
    "name": name.toJson,
    "middleName": middleName.toJson,
    "lastName": lastName.toJson,
  };
}
Generation

To run the generator call:

dart run metrica_generator 

By default it will look for the yaml-configurations in the lib/metrica folder but if you wish to store it somewhere else, specify it as a next argument like so:

dart run metrica_generator lib/generated/metrica

Calling the Functions

The events and types could be filled up by someone responsible for the analytics. They would define the events' structure and data to be sent. The only thing on the developer's side is to call the following function, which is as simple, as calling one function.

First, Create the Reporter
final reporter = MetricaReporter(AppMetricaReporter());
...
class AppMetricaReporter extends AbstractReporter {
  @override
  Future<void> reportEventWithMap(String key, body) =>
      AppMetrica.reportEventWithMap(key, body);
}
Send the Event!
reporter.reportUsersSelected([
    const User(id: '...', name: Name(name: 'Sam')),
    const User(id: '...', name: Name(middleName: 'Pete')),
    const User(id: '...', name: Name(name: 'John', lastName: 'Doe')),
]);

Contact me

The package is in development, so in case of problems or suggestions, feel free to create an issue on GitHub or contact me on Telegram.