Flutter事件追踪插件at_events_flutter的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter事件追踪插件at_events_flutter的使用

概述

at_events_flutter 包适用于希望在其应用中集成事件管理功能的Flutter开发者。这个开源包用Dart编写,支持Flutter,并遵循atPlatform的去中心化、边缘计算模型,具有以下特性:

  • 通过个人数据存储实现数据访问的加密控制
  • 不需要应用程序后端
  • 端到端加密,只有数据所有者拥有密钥
  • 私有且无监控连接
  • 创建和更新带有位置和参与者的事件

开始使用

快速开始 - 使用 at_app 生成骨架应用

此包包含一个工作示例应用程序在Example目录中,你可以使用at_app create命令创建个性化副本。

$ flutter pub global activate at_app 
$ at_app create --sample=<package ID> <app name> 
$ cd <app name>
$ flutter run

注意:

  1. 你只需要运行flutter pub global activate一次。
  2. 对于Windows,请使用at_app.bat
从GitHub克隆

可以从GitHub仓库克隆源代码。示例代码与上面提到的模板相同。

$ git clone https://github.com/atsign-foundation/at_widgets.git
手动添加包到项目

可以在pub.dev上找到手动添加包的说明。

如何工作

设置
初始化

应用程序首先应使用Onboarding小部件验证atsign。事件服务需要使用必需的GlobalKey进行初始化。

initialiseEventService(
  navKey,
  mapKey: 'xxxx', // 地图API密钥
  apiKey: 'xxxx',  // ETA计算API密钥
  rootDomain: 'root.atsign.org',
  streamAlternative: (__){},
  initLocation: true, // 是否初始化位置服务
);

由于该包需要位置权限,请在以下位置添加相应配置:

iOS (ios/Runner/Info.plist)

<key>NSLocationWhenInUseUsageDescription</key>
<string>解释描述内容。</string>

Android (android/app/src/main/AndroidManifest.xml)

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

at_events_flutter 依赖 at_location_flutter 实现以下功能:

  • 发送/接收位置,如果需要位置共享,则需初始化 at_location_flutter
  • 渲染地图,如果需要地图,则将 mapKey 传递给 initializeLocationService
  • 计算ETA,如果需要ETA,则将 apiKey 传递给 initializeLocationService
使用

要创建新事件,可以使用默认屏幕:

CreateEvent(
  AtClientManager.getInstance(),
),

使用事件创建/编辑功能时,确保先调用 EventService().init()

  • createEvent() - 根据 isEventUpdate 参数创建或编辑事件
  • editEvent() - 更新已创建的事件
  • sendEventNotification() - 创建新事件

导航到事件的地图屏幕:

EventsMapScreenData().moveToEventScreen(eventNotificationModel);

不同数据类型:

  • EventNotificationModel:包含事件详情并发送给atsigns。
  • EventKeyLocationModel:用于跟踪所有事件通知。

获取 mapKeyapiKey

示例代码

以下是完整的示例demo代码:

import 'dart:async';
import 'package:at_app_flutter/at_app_flutter.dart' show AtEnv;
import 'package:at_client_mobile/at_client_mobile.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart' show getApplicationSupportDirectory';

Future<void> main() async {
  await AtEnv.load();
  runApp(const MyApp());
}

Future<AtClientPreference> loadAtClientPreference() async {
  var dir = await getApplicationSupportDirectory();
  return AtClientPreference()
    ..rootDomain = AtEnv.rootDomain
    ..namespace = AtEnv.appNamespace
    ..hiveStoragePath = dir.path
    ..commitLogPath = dir.path
    ..isLocalStoreRequired = true;
}

final StreamController<ThemeMode> updateThemeMode = StreamController<ThemeMode>.broadcast();

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<AtClientPreference> futurePreference = loadAtClientPreference();
  AtClientPreference? atClientPreference;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return StreamBuilder<ThemeMode>(
      stream: updateThemeMode.stream,
      initialData: ThemeMode.light,
      builder: (BuildContext context, AsyncSnapshot<ThemeMode> snapshot) {
        ThemeMode themeMode = snapshot.data ?? ThemeMode.light;
        return MaterialApp(
          navigatorKey: NavService.navKey,
          theme: ThemeData().copyWith(
            brightness: Brightness.light,
            primaryColor: const Color(0xFFf4533d),
            colorScheme: ThemeData.light().colorScheme.copyWith(primary: const Color(0xFFf4533d), surface: Colors.white),
            scaffoldBackgroundColor: Colors.white,
          ),
          darkTheme: ThemeData().copyWith(
            brightness: Brightness.dark,
            primaryColor: Colors.blue,
            colorScheme: ThemeData.dark().colorScheme.copyWith(primary: Colors.blue, surface: Colors.grey[850]),
            scaffoldBackgroundColor: Colors.grey[850],
          ),
          themeMode: themeMode,
          home: Scaffold(
            appBar: AppBar(
              title: const Text('MyApp'),
              actions: <Widget>[
                IconButton(
                  onPressed: () {
                    updateThemeMode.sink.add(themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light);
                  },
                  icon: Icon(
                    Theme.of(context).brightness == Brightness.light
                        ? Icons.dark_mode_outlined
                        : Icons.light_mode_outlined,
                  ),
                )
              ],
            ),
            body: Builder(
              builder: (context) => Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () async {
                        var preference = await futurePreference;
                        setState(() {
                          atClientPreference = preference;
                        });
                        if (context.mounted) {
                          final result = await AtOnboarding.onboard(
                            context: context,
                            config: AtOnboardingConfig(
                              atClientPreference: atClientPreference!,
                              domain: AtEnv.rootDomain,
                              rootEnvironment: AtEnv.rootEnvironment,
                              appAPIKey: AtEnv.appApiKey,
                            ),
                          );
                          switch (result.status) {
                            case AtOnboardingResultStatus.success:
                              Navigator.push(context, MaterialPageRoute(builder: (_) => const SecondScreen()));
                              break;
                            case AtOnboardingResultStatus.error:
                              ScaffoldMessenger.of(context).showSnackBar(
                                const SnackBar(
                                  backgroundColor: Colors.red,
                                  content: Text('An error has occurred'),
                                ),
                              );
                              break;
                            case AtOnboardingResultStatus.cancel:
                              break;
                          }
                        }
                      },
                      child: const Text('Onboard an atSign'),
                    ),
                    const SizedBox(height: 10),
                    ElevatedButton(
                      onPressed: () async {
                        var preference = await futurePreference;
                        atClientPreference = preference;
                        if (context.mounted) {
                          AtOnboarding.reset(
                            context: context,
                            config: AtOnboardingConfig(
                              atClientPreference: atClientPreference!,
                              domain: AtEnv.rootDomain,
                              rootEnvironment: AtEnv.rootEnvironment,
                              appAPIKey: AtEnv.appApiKey,
                            ),
                          );
                        }
                      },
                      child: const Text('Reset'),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class NavService {
  static GlobalKey<NavigatorState> navKey = GlobalKey();
}

更多关于Flutter事件追踪插件at_events_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter事件追踪插件at_events_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用at_events_flutter插件进行事件追踪的示例代码。这个示例假设你已经有一个Flutter项目,并且已经添加了at_events_flutter依赖。

首先,确保你的pubspec.yaml文件中包含at_events_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  at_events_flutter: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤配置和使用at_events_flutter进行事件追踪。

1. 初始化AtEventsFlutter

在你的应用的主文件(通常是main.dart)中,初始化AtEventsFlutter实例。

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化AtEventsFlutter
  AtEventsFlutter.instance.initialize(
    appId: 'your_app_id',  // 替换为你的应用ID
    apiKey: 'your_api_key', // 替换为你的API密钥
    endpoint: 'https://your-events-endpoint.com', // 替换为你的事件追踪端点
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Event Tracking Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

2. 追踪事件

在你的应用中,你可以通过调用AtEventsFlutter.instance.track方法来追踪事件。例如,在一个按钮点击事件中追踪一个自定义事件:

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

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Event Tracking Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 追踪按钮点击事件
            trackButtonClickEvent();
          },
          child: Text('Track Event'),
        ),
      ),
    );
  }

  void trackButtonClickEvent() {
    Map<String, dynamic> eventProperties = {
      'button_name': 'track_button',
      'action': 'clicked',
      // 你可以添加更多自定义属性
    };

    AtEventsFlutter.instance.track(
      eventName: 'button_click',
      properties: eventProperties,
    );
  }
}

3. 运行应用

现在,当你运行应用并点击“Track Event”按钮时,事件将被发送到你在AtEventsFlutter.instance.initialize中配置的端点。

注意事项

  1. 依赖版本:确保你使用的是at_events_flutter的最新稳定版本。
  2. 隐私与安全:在实际应用中,确保你遵循隐私政策和数据保护法规,不要收集或发送敏感用户信息。
  3. 错误处理:为了健壮性,你可能需要添加错误处理逻辑来处理事件追踪失败的情况。

这个示例代码展示了如何在Flutter应用中使用at_events_flutter插件进行基本的事件追踪。根据你的具体需求,你可以进一步自定义和扩展事件追踪功能。

回到顶部