Flutter特性控制插件unleash_proxy的使用

Flutter特性控制插件unleash_proxy的使用

本库旨在与unleash-proxy一起使用。代理应用层将位于您的unleash实例和客户端应用程序之间,并提供性能和安全方面的优势。切勿尝试直接连接到unleash实例,因为数据集格式不同,代理仅返回评估后的开关信息。

安装 💻

❗ 要开始使用Unleash,必须在您的机器上安装Flutter SDK

pubspec.yaml文件中添加unleash_proxy

dependencies:
  unleash_proxy:

然后运行以下命令来安装它:

flutter packages get

使用

初始化Unleash Proxy

Unleash上下文和配置是初始化Unleash应用所必需的。

上下文

上下文的重要属性包括:

  • appName - 如果你使用依赖于哪个应用的策略。
  • userId - 渐进式分发策略通常使用此属性来决定粘性,以确定用户最终属于哪个用户组。
  • sessionId - 渐进式分发策略通常使用此属性来决定粘性。
  • properties - 如果你使用自定义策略。

示例:

UnleashContext(
  appName: 'APP_NAME',
  userId: 'USER_ID',
  sessionId: 'SESSION_ID',
  properties: {'variant': 'ios'},
);

更新当前上下文:

class UnleashScreen extends StatelessWidget {
  UnleashScreen({required this.unleash});
  final UnleashApp unleash;
  
  /// [updateContext] 方法将更新当前上下文
  Future<void> updateContext() async {
    await unleash.setContext(UnleashContext(
      properties: {'variant': 'ios'},
      userId: 'exampleId',
    ));
  }
}
配置

对于配置,必须设置两个变量,如果希望在轮询线程找到更新时收到通知,还应配置轮询模式:

  • proxyUrl - 您的代理安装位置。对于Unleash-Hosted的演示实例,这位于https://app.unleash-hosted.com/demo/proxy,但您的位置可能不同。
  • clientKey - 访问代理的API密钥。(从v0.4.0版本开始重命名为clientKey
  • pollMode - 查看PollingModes
  • bootstrap - 允许您通过json格式或List<UnleashToggle>启动特征开关缓存。
  • onFetched - 每次从服务器获取开关时运行一个函数。

示例:

UnleashOptions(
  proxyUrl: 'https://UNLEASH_URL/proxy',
  clientKey: 'CLIENT_KEY',
  poolMode: UnleashPollingMode.custom(const Duration(seconds: 5)),
  bootstrap: UnleashBootstrap(
    source: [
      UnleashToggle(
        enabled: true,
        name: 'testing-source',
        variant: UnleashToggleVariant(name: 'disabled', enabled: false),
      ),
    ],
    json: source,
  ),
  onFetched: (List<UnleashToggle> toggles) {
    debugPrint('Yay! ${toggles.length} toggles fetched.');
  },
)
轮询模式

为了根据服务器更新开关,必须在Unleash配置中设置轮询模式。默认情况下,轮询模式设置为15秒,但您可以将其设置为const Duration(seconds: 0),如果您不想使用开关间隔更新,或者可以通过自定义轮询模式来设置间隔持续时间。

如果您想立即停止轮询,可以调用dispose()。Unleash将使用最新的缓存来自缓存存储。

初始化

要在Flutter应用中使用unleash_proxy,首先需要初始化unleash_proxy。创建一个unleash_environment.dart文件以保存环境变量。以下是基本环境配置的代码示例:

import 'package:flutter/services.dart';
import 'package:unleash_proxy/unleash_proxy.dart';

class UnleashEnvironment {
  static UnleashOptions get config => UnleashOptions(
    proxyUrl: 'https://UNLEASH_URL/proxy',
    clientKey: 'CLIENT_KEY',
  );

  static UnleashContext get context => UnleashContext();
}

class ToggleKeys {
  static String experiment = 'toggle-experiment';
}

在主文件中初始化unleash_proxy

import 'package:example/unleash_environment.dart';
import 'package:flutter/material.dart';

/// 导入包
import 'package:unleash_proxy/unleash_proxy.dart';

Future<void> main() async {
  /// 如果需要在调用[runApp]之前初始化绑定,只需调用此方法
  WidgetsFlutterBinding.ensureInitialized();

  /// 初始化unleash客户端
  final unleashApp = await Unleash.initializeApp(
    options: await UnleashEnvironment.config,
    context: UnleashEnvironment.context,
  );

  runApp(App(app: unleashApp));
}

使用Unleash Proxy开关

import 'package:example/unleash_environment.dart';
import 'package:flutter/material.dart';
import 'package:unleash_proxy/unleash_proxy.dart';

class BasicUsageScreen extends StatelessWidget {
  const BasicUsageScreen({super.key, required this.app});

  final UnleashApp app;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Basic Usage'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'Toggle Status',
              style: TextStyle(height: 2.5, fontWeight: FontWeight.w500),
            ),
            toggleStatus(),
          ],
        ),
      ),
    );
  }

  Widget toggleStatus() {
    /// 调用[isEnabled]获取开关值
    final status = app.isEnabled(ToggleKeys.experiment);

    return Text(status == true ? 'Enabled' : 'Disabled');
  }
}

可以在这里查看完整的示例。


持续集成 🤖

Unleash Flutter Proxy SDK附带了一个由Very Good Workflows支持的内置GitHub Actions工作流,但您也可以添加自己的CI/CD解决方案。

默认情况下,在每次拉取请求和推送时,CI会格式化、检查和测试代码。这确保了代码的一致性和正确行为,无论您是添加功能还是进行更改。该项目使用Very Good Analysis来使用我们团队的严格分析选项。使用Very Good Workflows来强制执行代码覆盖率。


运行测试 🧪

对于新用户,安装very_good_cli

dart pub global activate very_good_cli

要运行所有单元测试:

very_good test --coverage

要查看生成的覆盖率报告,可以使用lcov

# 生成覆盖率报告
genhtml coverage/lcov.info -o coverage/

# 打开覆盖率报告
open coverage/index.html

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

1 回复

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


unleash_proxy 是一个用于 Flutter 的特性控制(Feature Toggle)插件,它允许你通过 Unleash 服务来动态地控制应用中的功能开关。Unleash 是一个开源的功能管理平台,可以帮助团队在不重新部署代码的情况下,动态地启用或禁用功能。

安装 unleash_proxy 插件

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

dependencies:
  flutter:
    sdk: flutter
  unleash_proxy: ^1.0.0  # 请使用最新的版本

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

初始化 UnleashProxy

在你的 Flutter 应用中,你需要初始化 UnleashProxy 实例。通常,你可以在 main.dart 文件中进行初始化。

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化 UnleashProxy
  final unleash = UnleashProxy(
    url: 'https://your-unleash-proxy-url.com/proxy', // Unleash Proxy 的 URL
    clientKey: 'your-client-key', // 客户端密钥
    appName: 'your-app-name', // 应用名称
  );

  // 启动应用
  runApp(MyApp(unleash: unleash));
}

class MyApp extends StatelessWidget {
  final UnleashProxy unleash;

  MyApp({required this.unleash});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(unleash: unleash),
    );
  }
}

使用 UnleashProxy 控制功能

在应用中使用 UnleashProxy 来控制功能的启用或禁用。例如,你可以在 MyHomePage 中根据功能的开关状态来显示不同的 UI。

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

class MyHomePage extends StatefulWidget {
  final UnleashProxy unleash;

  MyHomePage({required this.unleash});

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isFeatureEnabled = false;

  [@override](/user/override)
  void initState() {
    super.initState();
    _checkFeature();
  }

  Future<void> _checkFeature() async {
    final isEnabled = await widget.unleash.isEnabled('my-feature-toggle');
    setState(() {
      isFeatureEnabled = isEnabled;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      ),
      body: Center(
        child: isFeatureEnabled
            ? Text('Feature is enabled!')
            : Text('Feature is disabled.'),
      ),
    );
  }
}
回到顶部