thinking_analytics 1.1.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 50

thinking_analytics #

The Official Thinking Analytics Flutter plugin. Used to track events and user properties to Thinking Analytics.

Getting Started #

To use this plugin, add thinking_analytics as a dependency in your pubspec.yaml file.

Find the APP ID and Server URL from your Thinking Analytics project settings and TA cluster administrator.

Import package:thinking_analytics/thinking_analytics.dart, and get an instance of ThinkingAnalyticsAPI with your APP ID and Server URL.

In the example below - replace the string APP_ID and SERVER_URL with your own APP ID and Server URL.

In addition, several named parameters are allowed to be passed to the getInstance function for additional options, including:

  • timeZone: default timeZone in native for serializing date to string of required format.
  • mode: [ThinkingAnalyticsMode]. Currently we support 3 modes including normal, debug, and debug only.

Example #

import 'package:thinking_analytics/thinking_analytics.dart';


Future<void> example() async {
  final ThinkingAnalyticsAPI ta = await ThinkingAnalyticsAPI.getInstance('APP_ID', 'https://SERVER_URL');

  // optional. set your own distinct ID as an anonymous ID
  ta.identify('you distinct ID');

  // optional. set account ID for the user
  ta.login('the account ID');

  // track an simple event.
  ta.track('example_event');

  // track an event with properties
  ta.track('another_event', properties: <String, dynamic>{
    'PROP_INT': 5678,
    'PROP_DOUBLE': 12.3,
    'PROP_DATE': DateTime.now(),
    'PROP_LIST': ['apple', 'ball', 1234],
    'PROP_BOOL': false,
    'PROP_STRING': 'flutter test',
    });

  // set user properties
  ta.userSet(<String, dynamic>{
    'USER_INT': 1,
    'USER_DOUBLE': 50.12,
    'USER_LIST': ['apple', 'ball', 'cat', 1, DateTime.now().toUtc()],
    'USER_BOOL': true,
    'USER_STRING': 'a user value',
    'USER_DATE': DateTime.now(),
    });

  // optional. post local data to server immediately
  ta.flush();
}

1.1.1 #

  • 修复 Android 平台 DEBUG 模式事件上报 BUG

1.1.0 #

  • 支持使用服务端时间校准 SDK 时间

1.0.0 #

  • 支持事件和用户属性数据上报
  • 支持多实例和轻实例
  • 支持公共事件属性和动态公共属性
  • 支持自动采集事件
  • 支持 Debug 模式
  • 支持设置默认时区

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:thinking_analytics/thinking_analytics.dart';

void main() => runApp(new MaterialApp(home: MyApp()));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

enum USER_OPERATIONS {
  USER_SET,
  USER_SET_ONCE,
  USER_ADD,
  USER_DEL,
  USER_UNSET,
  USER_APPEND,
}

enum SUPER_PROPERTY_OPERATIONS {
  SET,
  CLEAR,
  UNSET
}

enum INSTANCE_OPERATIONS {
  TRACK,
  LOGIN,
  LOGOUT,
  FLUSH,
  INFO,
}

class _MyAppState extends State<MyApp> {
  ThinkingAnalyticsAPI _ta;
  ThinkingAnalyticsAPI _ta2;
  ThinkingAnalyticsAPI _light;

  @override
  void initState() {
    super.initState();
    initThinkingDataState();
  }

  Future<void> initThinkingDataState() async {
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {});

    // 打开日志
    ThinkingAnalyticsAPI.enableLog();

    // 初始化 _ta 实例
    _ta = await ThinkingAnalyticsAPI.getInstance('b2a61feb9e56472c90c5bcb320dfb4ef', 'https://sdk.tga.thinkinggame.cn');

    // 设置动态公共属性, 动态公共属性不支持自动采集事件
    _ta.setDynamicSuperProperties((){
      return <String, dynamic> {
        'DYNAMIC_DATE': DateTime.now().toUtc(),
        'PROP_INT': 8888
      };
    });

    _ta.setSuperProperties(<String, dynamic>{
      'SUPER_START_TIME': DateTime.now()
    });

    _ta.enableAutoTrack([
      ThinkingAnalyticsAutoTrackType.APP_START,
      ThinkingAnalyticsAutoTrackType.APP_END,
      ThinkingAnalyticsAutoTrackType.APP_INSTALL,
      ThinkingAnalyticsAutoTrackType.APP_CRASH,
    ]);

    // 初始化轻实例
    _light = await _ta.createLightInstance();
    _light.identify('light_d_id');

    // 初始化 _ta2 实例,对齐 UTC 时区,开启 DEBUG 模式
    _ta2 = await ThinkingAnalyticsAPI.getInstance( '31c880c46c9543149330b1d56cb9f9c3', 'https://sdk.tga.thinkinggame.cn',
      timeZone: 'UTC',
      mode: ThinkingAnalyticsMode.DEBUG,
    );
    _ta2.identify('ta2_d_id');

  }

  @override
  Widget build(BuildContext context) {
    List<Widget> buttons = [
      RaisedButton(
          child: Text('TRACK AN EVENT'), onPressed: () => trackEvent()),
      RaisedButton(
          child: Text('TIME EVENT'), onPressed: () => _ta.timeEvent('TEST_EVENT')),
      RaisedButton(
          child: Text('LOGIN'), onPressed: () => _ta.login('FLUTTER_A_ID')),
      RaisedButton(
          child: Text('LOGOUT'), onPressed: () => _ta.logout()),
      RaisedButton(
          child: Text('SUPER PROPERTIES'),
          onPressed: () => superPropertiesOperations()),
      RaisedButton(
        child: Text('USER PROPERTIES'),
        onPressed: () => userOperations(),
      ),
      RaisedButton(child: Text('FLUSH'), onPressed: () => flush()),
      RaisedButton(
          child: Text('SHOW SDK INFO'), onPressed: () => getSDKInfo(_ta)),
      RaisedButton(
        child: Text('LIGHT INSTANCE'), onPressed: () => instanceOperations(_light, 'light'), ),
      RaisedButton(
        child: Text('ANOTHER INSTANCE'), onPressed: () => instanceOperations(_ta2, 'another'), ),
    ];

    return MaterialApp(
      theme: ThemeData(
          //buttonTheme: ButtonThemeData(minWidth: double.infinity),
          ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: buttons,
        )),
      ),
    );
  }

  Future<void> getSDKInfo(ThinkingAnalyticsAPI instance) async {
    String distinctId = await instance.getDistinctId();
    String deviceId = await instance.getDeviceId();

    showDialog(
        context: context,
        builder: (context) {
          return new SimpleDialog(
            title: new Text("SDK Info"),
            children: <Widget>[
              new SimpleDialogOption(
                child: new Text("Distinct ID: " + distinctId),
              ),
              new SimpleDialogOption(
                child: new Text("Device ID: " + deviceId),
              ),
            ],
          );
        });
  }


  Future<void> userOperations() async {
      switch (await showDialog<USER_OPERATIONS>(
          context: context,
          builder: (BuildContext context) {
            return SimpleDialog(
              title: const Text('Select assignment'),
              children: <Widget>[
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_SET); },
                  child: const Text('USER SET'),
                ),
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_SET_ONCE); },
                  child: const Text('USER SET ONCE'),
                ),
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_APPEND); },
                  child: const Text('USER APPEND'),
                ),
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_ADD); },
                  child: const Text('USER ADD'),
                ),
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_UNSET); },
                  child: const Text('USER UNSET'),
                ),
                SimpleDialogOption(
                  onPressed: () { Navigator.pop(context, USER_OPERATIONS.USER_DEL); },
                  child: const Text('USER DEL'),
                ),

              ],
            );
          }
      )) {
        case USER_OPERATIONS.USER_SET:
          _ta.userSet(<String, dynamic>{
            'USER_INT': 1,
            'USER_DOUBLE': 50.12,
            'USER_LIST': ['apple', 'ball', 'cat', 1, DateTime.now().toUtc()],
            'USER_BOOL': true,
            'USER_STRING': 'a user value',
            'USER_DATE': DateTime.now(),
          });
          break;
        case USER_OPERATIONS.USER_SET_ONCE:
          _ta.userSetOnce(<String, dynamic>{
            'USER_INT': 2,
            'USER_DOUBLE': 10.12,
          });
          break;
        case USER_OPERATIONS.USER_APPEND:
          _ta.userAppend(<String, List>{
            'USER_LIST': [DateTime.now()],
          });
          break;
        case USER_OPERATIONS.USER_ADD:
          _ta.userAdd(<String, num>{
            'USER_INT': 2,
            'USER_DOUBLE': 10.1,
          });
          break;
        case USER_OPERATIONS.USER_UNSET:
          _ta.userUnset('USER_INT');
          break;
        case USER_OPERATIONS.USER_DEL:
          _ta.userDelete();
          break;
      }
  }

  Future<void> superPropertiesOperations() async {
    switch (await showDialog<SUPER_PROPERTY_OPERATIONS>(
        context: context,
        builder: (BuildContext context) {
          return SimpleDialog(
            title: const Text('SUPER PROPERTIES'),
            children: <Widget>[
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, SUPER_PROPERTY_OPERATIONS.SET); },
                child: const Text('SET SUPER PROPERTIES'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, SUPER_PROPERTY_OPERATIONS.CLEAR); },
                child: const Text('CLEAR SUPER PROPERTIES'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, SUPER_PROPERTY_OPERATIONS.UNSET); },
                child: const Text('UNSET A SUPER PROPERTY'),
              ),

            ],
          );
        }
    )) {
      case SUPER_PROPERTY_OPERATIONS.SET:
        Map<String, dynamic> superProperties = {
          'SUPER_STRING': 'super string value',
          'SUPER_INT': 1234,
          'SUPER_DOUBLE': 66.88,
          'SUPER_DATE': DateTime.now(),
          'SUPER_BOOL': true,
          'SUPER_LIST': [1234, 'hello', DateTime.now().toUtc()]
        };

        _ta.setSuperProperties(superProperties);
        break;
      case SUPER_PROPERTY_OPERATIONS.CLEAR:
        _ta.clearSuperProperties();
        break;
      case SUPER_PROPERTY_OPERATIONS.UNSET:
        _ta.unsetSuperProperty('SUPER_LIST');
        break;
    }

  }

  void trackEvent() {
    _ta.track('TEST_EVENT', properties: <String, dynamic>{
      'PROP_INT': 5678,
      'PROP_DOUBLE': 12.3,
      'PROP_DATE': DateTime.now().toUtc(),
      'PROP_LIST': ['apple', 'ball', 1234],
      'PROP_BOOL': false,
      'PROP_STRING': 'flutter test',
    });
  }

  void flush() {
    _ta.flush();
  }


  Future<void> instanceOperations(ThinkingAnalyticsAPI instance, String prefix) async {
    switch (await showDialog<INSTANCE_OPERATIONS>(
        context: context,
        builder: (BuildContext context) {
          return SimpleDialog(
            title: Text('INSTANCE: ' + prefix),
            children: <Widget>[
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, INSTANCE_OPERATIONS.TRACK); },
                child: const Text('TRACK AN EVENT'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, INSTANCE_OPERATIONS.LOGIN); },
                child: const Text('LOGIN'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, INSTANCE_OPERATIONS.LOGOUT); },
                child: const Text('LOGOUT'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, INSTANCE_OPERATIONS.FLUSH); },
                child: const Text('FLUSH'),
              ),
              SimpleDialogOption(
                onPressed: () { Navigator.pop(context, INSTANCE_OPERATIONS.INFO); },
                child: const Text('SHOW SDK INFO'),
              ),

            ],
          );
        }
    )) {
      case INSTANCE_OPERATIONS.TRACK:
        instance.track(prefix + '_TEST');
        break;
      case INSTANCE_OPERATIONS.LOGIN:
        instance.login(prefix + '_aid');
        break;
      case INSTANCE_OPERATIONS.LOGOUT:
        instance.logout();
        break;
      case INSTANCE_OPERATIONS.FLUSH:
        instance.flush();
        break;
      case INSTANCE_OPERATIONS.INFO:
        getSDKInfo(instance);
        break;
    }
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  thinking_analytics: ^1.1.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:thinking_analytics/thinking_analytics.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
50
Learn more about scoring.

We analyzed this package on May 26, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.1
  • pana: 0.13.8-dev
  • Flutter: 1.17.0

Health suggestions

Format lib/thinking_analytics.dart.

Run flutter format to format lib/thinking_analytics.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8