Flutter特性管理插件flutter_bucketeer的使用
Flutter特性管理插件flutter_bucketeer的使用
概述
本文将详细介绍如何在Flutter项目中使用特性管理插件flutter_bucketeer
。我们将通过一个完整的示例来展示如何集成该插件并进行基本操作。
安装
首先,确保你的项目已经安装了必要的依赖项。在项目的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter_bucketeer: ^1.x.x
然后运行以下命令来获取这些依赖项:
$ flutter pub get
示例代码
接下来,我们将展示如何在Flutter应用中使用flutter_bucketeer
插件。以下是完整的示例代码:
import 'package:bucketeer_example/snack_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bucketeer/bucketeer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:ua_client_hints/ua_client_hints.dart';
const keyUserId = 'key_user_id';
Future<Map<String, String>> userMap() async {
final uaData = await userAgentData();
return {
'platform': uaData.platform, // 例如: 'Android'
'platformVersion': uaData.platformVersion, // 例如: '10'
'device': uaData.device, // 例如: 'coral'
'appName': uaData.package.appName, // 例如: 'SampleApp'
'appVersion': uaData.package.appVersion, // 例如: '1.0.0'
'packageName': uaData.package.packageName, // 例如: 'jp.wasabeef.ua'
'buildNumber': uaData.package.buildNumber, // 例如: '1'
};
}
class MyApp extends StatefulWidget {
[@override](/user/override)
State<MyApp> createState() {
return _AppState();
}
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Bucketeer.instance
..initialize(
apiKey: 'YOUR_API_KEY',
endpoint: 'YOUR_ENDPOINT.bucketeer.jp',
featureTag: 'Flutter',
debugging: true,
logSendingIntervalMillis: 3000,
logSendingMaxBatchQueueCount: 3,
pollingEvaluationIntervalMillis: 3000,
);
runApp(MyApp());
}
class _AppState extends State<MyApp> with WidgetsBindingObserver {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Bucketeer Demo'),
);
}
[@override](/user/override)
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed) {
Bucketeer.instance.start();
} else if (state == AppLifecycleState.paused) {
Bucketeer.instance.stop();
}
}
[@override](/user/override)
void initState() {
super.initState();
Future(() async {
// 生成用户ID用于演示
final prefs = await SharedPreferences.getInstance();
final userId = prefs.getString(keyUserId);
if (userId == null) {
await prefs.setString(
keyUserId, 'demo-userId-${DateTime.now().millisecondsSinceEpoch}');
} else {
await Bucketeer.instance.setUser(userId, userMap: await userMap());
}
});
WidgetsBinding.instance.addObserver(this);
}
[@override](/user/override)
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final flagController = TextEditingController(text: 'bucketeer-feature-flag');
final goalController = TextEditingController(text: 'bucketeer-goal-id');
final userIdController = TextEditingController(text: 'bucketeer-flutter-user-id');
Future<void> _getStringVariation(String featureId) async {
final result = await Bucketeer.instance
.getStringVariation(featureId, defaultValue: 'default value');
result.ifSuccess((data) {
print('getStringVariation: ${data}');
showSnackbar(
context: context, title: 'getStringVariation', message: data);
});
}
Future<void> _getIntVariation(String featureId) async {
final result =
await Bucketeer.instance.getIntVariation(featureId, defaultValue: 0);
result.ifSuccess((data) {
print('getIntVariation: $data');
showSnackbar(
context: context, title: 'getIntVariation', message: '$data');
});
}
Future<void> _getDoubleVariation(String featureId) async {
final result = await Bucketeer.instance
.getDoubleVariation(featureId, defaultValue: 0.0);
result.ifSuccess((data) {
print('getDoubleVariation: $data');
showSnackbar(
context: context, title: 'getDoubleVariation', message: '$data');
});
}
Future<void> _getBoolVariation(String featureId) async {
final result = await Bucketeer.instance
.getBoolVariation(featureId, defaultValue: false);
result.ifSuccess((data) {
print('getBoolVariation: $data');
showSnackbar(
context: context, title: 'getBoolVariation', message: '$data');
});
}
Future<void> _getEvaluation(String featureId) async {
final result = await Bucketeer.instance.getEvaluation(featureId);
result.ifSuccess((evaluation) {
print('Successful the evaluation');
showSnackbar(
context: context,
title: 'getEvaluation(${evaluation.toString()})',
message: 'Successful the evaluation.');
});
}
Future<void> _sendGoal(String goalId) async {
final result = await Bucketeer.instance.track(goalId, value: 3.1412);
if (result.isSuccess) {
print('Successful the send goal.');
showSnackbar(
context: context,
title: 'sendGoal',
message: 'Successful the send goal.');
} else {
print('Failed the send goal.');
showSnackbar(
context: context,
title: 'sendGoal',
message: 'Failed the send goal.');
}
}
Future<void> _switchUser(String userId) async {
final result =
await Bucketeer.instance.setUser(userId, userMap: await userMap());
result.ifSuccess((_) {
print('Successful the setUser');
showSnackbar(
context: context,
title: 'setUser',
message: 'Successful the setUser.');
});
}
Future<void> _getCurrentUser() async {
final result = await Bucketeer.instance.getUser();
result.ifSuccess((user) {
print('Successful the getUser');
showSnackbar(
context: context,
title: 'getUser(${user.id})',
message: 'Successful the getUser.');
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 36.0),
Text(
'Feature Flag Id',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextFormField(
controller: flagController,
decoration:
InputDecoration(hintText: 'bucketeer-feature-flag'),
),
const SizedBox(height: 12),
Text('GET VARIATION',
style: TextStyle(fontWeight: FontWeight.bold)),
Wrap(
spacing: 8,
children: [
TextButton(
child: Text('GET String param'),
onPressed: () async {
return _getStringVariation(flagController.text);
}),
TextButton(
child: Text('GET int param'),
onPressed: () async {
return _getIntVariation(flagController.text);
}),
TextButton(
child: Text('GET double params'),
onPressed: () async {
return _getDoubleVariation(flagController.text);
}),
TextButton(
child: Text('GET bool params'),
onPressed: () async {
return _getBoolVariation(flagController.text);
}),
TextButton(
child: Text('GET evalution'),
onPressed: () async {
return _getEvaluation(flagController.text);
}),
],
),
SizedBox(height: 36.0),
Text(
'Goal Id',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextFormField(
controller: goalController,
decoration: InputDecoration(hintText: goalController.text),
),
TextButton(
child: Text('SEND GOAL'),
onPressed: () async {
return _sendGoal(goalController.text);
}),
SizedBox(height: 36.0),
Text(
'User Id',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextFormField(
controller: userIdController,
decoration:
InputDecoration(hintText: userIdController.text),
),
Row(
children: [
TextButton(
child: Text('SWITCH USER'),
onPressed: () async {
return _switchUser(userIdController.text);
}),
TextButton(
child: Text('GET CURRENT USER'),
onPressed: () async {
return _getCurrentUser();
},
)
],
),
],
),
),
),
),
),
);
}
}
更多关于Flutter特性管理插件flutter_bucketeer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter特性管理插件flutter_bucketeer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_bucketeer
是一个用于 Flutter 的特性管理插件,它可以帮助你在应用中实现特性标志(Feature Flags)的管理。特性标志允许你在不重新部署应用的情况下,动态地开启或关闭某些功能。这在 A/B 测试、逐步推出新功能或快速回滚问题功能时非常有用。
1. 安装 flutter_bucketeer
首先,你需要在 pubspec.yaml
文件中添加 flutter_bucketeer
依赖:
dependencies:
flutter:
sdk: flutter
flutter_bucketeer: ^0.1.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 初始化 flutter_bucketeer
在你的 Flutter 应用中初始化 flutter_bucketeer
。你可以在应用的 main.dart
文件中进行初始化:
import 'package:flutter/material.dart';
import 'package:flutter_bucketeer/flutter_bucketeer.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化 Bucketeer
await Bucketeer.init(
apiKey: 'YOUR_API_KEY',
userId: 'USER_ID', // 可以是用户的唯一标识符
countryCode: 'US', // 可选
appVersion: '1.0.0', // 可选
);
runApp(MyApp());
}
3. 获取特性标志
在初始化之后,你可以通过 Bucketeer
类来获取特性标志的值。特性标志可以是布尔值、字符串、数字等类型。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 获取特性标志
bool isFeatureEnabled = Bucketeer.getBool('feature_flag_key', defaultValue: false);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Bucketeer Example'),
),
body: Center(
child: isFeatureEnabled
? Text('Feature is enabled!')
: Text('Feature is disabled!'),
),
),
);
}
}
4. 更新特性标志
你可以使用 Bucketeer
的 update
方法来手动更新特性标志。这对于在特定事件或用户操作后重新获取最新的特性标志非常有用。
void updateFeatureFlags() async {
await Bucketeer.update();
}
5. 处理特性标志的变化
flutter_bucketeer
还允许你监听特性标志的变化,以便在标志值发生变化时做出相应的处理。
Bucketeer.addListener('feature_flag_key', (value) {
print('Feature flag changed to: $value');
});