Flutter特性管理插件launchdarkly_flutter_client_sdk的使用

Flutter特性管理插件launchdarkly_flutter_client_sdk的使用

LaunchDarkly Client-side SDK for Flutter

Action Status Pub

LaunchDarkly 是一个功能管理平台,每天提供数万亿个功能标记,帮助团队更快地构建更好的软件。开始使用 LaunchDarkly!

Twitter Follow

平台支持

平台 支持情况
Android ✅
iOS ✅
MacOS ✅
Web ✅
Linux ✅
Windows ✅

快速开始

请参考 SDK 文档 获取如何开始使用该 SDK 的说明。

了解更多

阅读我们的 文档 以获取配置和使用 LaunchDarkly 的深入说明。您也可以直接前往 此 SDK 的完整参考指南 或 代码生成的 API 文档。

测试

我们为所有 SDK 运行集成测试,使用集中式测试框架。这种方法使我们能够跨 SDK 测试一致性。这些测试涵盖了 SDK 中的每个方法,并验证事件发送、标志评估、流重新连接等方面是否正确工作。

贡献

我们鼓励来自社区的拉取请求和其他贡献。请阅读我们的 贡献指南 了解如何为此 SDK 做出贡献。

关于 LaunchDarkly

  • LaunchDarkly 是一个功能管理平台。我们赋能所有团队交付并控制他们的软件。使用 LaunchDarkly,您可以:
    • 向一部分最终用户推出新功能,例如加入 beta 测试者组的用户,并从真实用例中收集反馈和错误报告。
    • 逐步向越来越多的客户推出功能,并跟踪该功能对关键指标的影响。例如,拥有功能 A 和功能 B 的客户完成购买的可能性有多大?
    • 关闭在生产环境中引起性能问题的功能,而无需重新部署或甚至重启应用程序。
    • 根据最终用户的属性(如支付计划)授予对某些功能的访问权限。(例如,“黄金”计划的客户比“银色”计划的客户有更多功能访问权限。)
    • 在不完全下线的情况下停用应用程序的部分以进行维护。
  • LaunchDarkly 提供了广泛语言和技术的功能标记 SDK。请参阅我们的 SDK 文档 获取完整列表。
  • 探索 LaunchDarkly

示例代码

下面是一个完整的示例代码,展示了如何在 Flutter 应用程序中使用 launchdarkly_flutter_client_sdk 插件来管理功能标记。

import 'package:flutter/material.dart';
import 'package:launchdarkly_flutter_client_sdk/launchdarkly_flutter_client_sdk.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Provider<LDClient>(
      create: (_) => LDClient(
        LDConfig(
          // 使用环境变量设置凭据
          CredentialSource.fromEnvironment(),
          AutoEnvAttributes.enabled,
        ),
        LDContextBuilder().kind('user', 'user-key').build(),
      ),
      dispose: (_, client) => client.close(),
      child: MaterialApp(
        title: 'LaunchDarkly Example',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const MyHomePage(title: 'LaunchDarkly Example'),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class FlagProviderString extends StreamProvider<String> {
  FlagProviderString({
    super.key,
    required LDClient client,
    required String flagKey,
    required String defaultValue,
    required Widget child,
  }) : super(
          create: (context) => client.flagChanges
              .where((element) => element.keys.contains(flagKey))
              .map((event) => client.stringVariation(flagKey, defaultValue)),
          initialData: client.stringVariation(flagKey, defaultValue),
          child: child,
        );
}

class _MyHomePageState extends State<MyHomePage> {
  final _userKeyController = TextEditingController(text: 'user-key');
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: FutureBuilder(
        future: Provider.of<LDClient>(context, listen: false)
            .start()
            .timeout(const Duration(seconds: 5), onTimeout: () => true)
            .then((value) => true),
        builder: (context, loaded) => loaded.data ?? false
            ? Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Form(
                      key: _formKey,
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          TextFormField(
                            validator: (value) {
                              if (value == null || value.isEmpty) {
                                return 'Please enter a user key';
                              }
                              return null;
                            },
                            controller: _userKeyController,
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 16),
                            child: ElevatedButton(
                              onPressed: () {
                                if (_formKey.currentState!.validate()) {
                                  final client = Provider.of<LDClient>(
                                      context,
                                      listen: false);

                                  client
                                      .identify(LDContextBuilder()
                                          .kind('user', _userKeyController.text)
                                          .build())
                                      .then((value) {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(content: Text('Identify complete')),
                                    );
                                  });
                                }
                              },
                              child: const Text('Identify'),
                            ),
                          ),
                        ],
                      ),
                    ),
                    FlagProviderString(
                      client: Provider.of<LDClient>(context, listen: false),
                      flagKey: 'string-flag',
                      defaultValue: 'default-value',
                      child: Consumer<String>(
                        builder: (context, flagValue, _) =>
                            Text('flag value: $flagValue'),
                      ),
                    ),
                  ],
                ),
              )
            : const CircularProgressIndicator(),
      ),
    );
  }
}

代码解释

  1. 初始化 SDK:在 main.dart 文件中,通过 Provider 包装整个应用程序,确保 LDClient 在应用程序生命周期内保持不变。
  2. 配置 SDK:使用 LDConfig 和 LDContextBuilder 初始化 LDClient,并通过环境变量设置凭据。
  3. 启动 SDK:使用 FutureBuilder 等待 SDK 启动完成,或者超时后继续执行。
  4. 标识用户:通过表单输入用户键,并调用 identify 方法更新当前用户。
  5. 监听功能标记变化:使用 FlagProviderString 监听特定功能标记的变化,并显示其值。

通过以上步骤,您可以轻松地在 Flutter 应用程序中集成和使用 LaunchDarkly 的功能管理平台。


更多关于Flutter特性管理插件launchdarkly_flutter_client_sdk的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter特性管理插件launchdarkly_flutter_client_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用launchdarkly_flutter_client_sdk插件来进行特性管理的代码示例。这个插件允许你与LaunchDarkly服务集成,从而进行远程特性标志(feature flags)的管理。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加launchdarkly_flutter_client_sdk依赖:

dependencies:
  flutter:
    sdk: flutter
  launchdarkly_flutter_client_sdk: ^x.y.z  # 替换为最新版本号

2. 初始化LaunchDarkly客户端

在你的Flutter项目的main.dart文件或类似的入口文件中,初始化LaunchDarkly客户端。你需要提供SDK密钥(SDK Key)和相关的配置。

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

void main() {
  runApp(MyApp());
}

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

class _MyAppState extends State<MyApp> {
  LDClient? ldClient;

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

  void initLaunchDarkly() async {
    // 替换为你的SDK密钥
    final String sdkKey = "your-sdk-key-here";
    
    // 创建LDConfig对象,可以根据需要添加更多配置
    final LDConfig config = LDConfig.builder()
      ..withStream(true) // 启用实时更新
      ..build();

    // 初始化LDClient
    ldClient = await LDClient.init(sdkKey, config);

    // 监听特性标志的变化(可选)
    ldClient?.addListener((flagKey, flagValue, oldValue) {
      print("Flag ${flagKey} changed from $oldValue to $flagValue");
    });

    // 检查某个特性标志的值(示例)
    checkFeatureFlag();
  }

  void checkFeatureFlag() async {
    if (ldClient != null) {
      final bool featureEnabled = await ldClient!.boolValue(forKey: "my-feature-flag");
      print("My Feature Flag is enabled: $featureEnabled");
      
      // 根据特性标志的值更新UI(示例)
      // setState(() {
      //   // 更新UI逻辑
      // });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('LaunchDarkly Flutter Example'),
        ),
        body: Center(
          child: Text('Check console for feature flag values.'),
        ),
      ),
    );
  }
}

3. 使用特性标志

在你的Flutter应用中,你可以在任何地方使用ldClient来获取特性标志的值,并根据这些值来改变应用的行为或UI。

// 假设你有一个按钮,根据特性标志的值来决定是否显示
Widget buildButton() {
  return FutureBuilder<bool>(
    future: ldClient!.boolValue(forKey: "show-button-feature-flag"),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        bool showButton = snapshot.data ?? false;
        return showButton
            ? ElevatedButton(
                onPressed: () {
                  // 按钮点击事件
                },
                child: Text('Click Me!'))
            : Container(); // 如果特性标志为false,则不显示按钮
      } else {
        return Container(); // 等待特性标志值加载完成
      }
    },
  );
}

4. 运行应用

确保你的LaunchDarkly项目已经设置好相应的特性标志,并且SDK密钥是有效的。然后运行你的Flutter应用,你应该能够在控制台看到特性标志的值,并且UI会根据这些值进行相应更新。

这个示例展示了如何初始化LaunchDarkly客户端、监听特性标志的变化以及在Flutter应用中使用特性标志来改变UI。根据你的需求,你可以进一步扩展这些功能。

回到顶部