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
更多关于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.'),
),
);
}
}