import 'dart:math';
import 'package:flutter/material.dart';
import 'package:eyeofcloud_flutter_sdk/eyeofcloud_flutter_sdk.dart';
import 'dart:async';
// NOTE: You need to change this SDK key to your project's SDK Key
const String sdkKey = "Your_SDK_Key";
const String logTag = "EYEOFCLOUD_QUICK_START";
void main() {
runApp(const MyApp());
var productSorter = ProductSorter();
productSorter.initializeQuickStart();
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String uiResponse = 'Unknown';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Quick start example app'),
),
body: Center(
child: Text(uiResponse),
),
),
);
}
}
class ProductSorter {
String _datafileHost = "https://cdn.eyeofcloud.com";
String _datafileSuffixAndroid = "/datafiles/%s.json";
String _datafileSuffixIOS = "/datafiles/%@.json";
Future<void> initializeQuickStart() async {
// Setting up custom datafile URL format
Map<ClientPlatform, DatafileHostOptions> datafileHostOptions = {};
datafileHostOptions[ClientPlatform.android] =
DatafileHostOptions(_datafileHost, _datafileSuffixAndroid);
datafileHostOptions[ClientPlatform.iOS] =
DatafileHostOptions(_datafileHost, _datafileSuffixIOS);
// Initializing EyeofcloudClient
var flutterSDK = EyeofcloudFlutterSdk(
sdkKey, datafileHostOptions: datafileHostOptions);
var response = await flutterSDK.initializeClient();
if (response.success) {
flutterSDK.addConfigUpdateNotificationListener((msg) {
runQuickStart(flutterSDK);
});
await runQuickStart(flutterSDK);
}
}
Future<void> runQuickStart(EyeofcloudFlutterSdk flutterSDK) async {
/* --------------------------------
* to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
* --------------------------------
*/
// simulate 50 users
var rangeMax = 9999;
var rangeMin = 1000;
var range = Random();
var hasOnFlags = false;
for (int i = 0; i < 10; i++) {
var userId = "${range.nextInt(rangeMax - rangeMin) + rangeMin}";
/* --------------------------------
Create hardcoded user & bucket user into a flag variation
--------------------------------
*/
var user = await flutterSDK.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
var decisionResponse = await user!.decide("product_sort");
var decision = decisionResponse.decision;
// did decision fail with a critical error?
if (decision?.variationKey == null) {
print("\n\n$logTag decision error: ${decisionResponse.reason}");
}
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
String sortMethod = decision?.variables["sort_method"] as String;
if (decision!.enabled) {
// Keep count how many visitors had the flag enabled
hasOnFlags = true;
}
/* --------------------------------
Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
--------------------------------
*/
var userIdResponse = await user.getUserId();
// always returns false until you enable a flag rule in your Eyeofcloud project
print("\n\n$logTag Flag ${(decision.enabled
? "on"
: "off")}. User number ${userIdResponse.userId} saw flag variation: ${decision
.variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision
.ruleKey}");
}
if (!hasOnFlags) {
print(
"\n\n$logTag Flag was off for everyone. Some reasons could include:" +
"\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop" +
"\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." +
"\nCheck your key at https://app.eyeofcloud.com/v2/projects/YOUR_PROJECT_ID/settings/implementation");
}
}
}
在 Android Studio 中,启动模拟器。单击“运行”以执行之前创建的示例应用代码。输出类似于以下内容:
PowerShell
Flag on. User number 6998 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 1177 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 9714 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 4140 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 4994 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag off. User number 8700 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913
Flag off. User number 9912 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913
Flag on. User number 6560 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 9252 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 6582 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
var user = await eyeofcloudClient.createUserContext(userId);
// "product_sort" corresponds to the flag key you create in the Eyeofcloud app
var decideResponse = await user!.decide("product_sort");
// always returns false until you enable a flag rule in the Eyeofcloud app
if (decideResponse.decision!.enabled) {
// "sort_method" corresponds to variable key you define in Eyeofcloud app
var sortMethod = decideResponse.decision!.variables["sort_method"] as String;
print("sort_method: $sortMethod");
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:eyeofcloud_flutter_sdk/eyeofcloud_flutter_sdk.dart';
import 'dart:async';
import 'package:eyeofcloud_flutter_sdk/src/user_context/eyeofcloud_user_context.dart';
// NOTE: You need to change this SDK key to your project's SDK Key
const String sdkKey = "Your_SDK_Key";
const String logTag = "EYEOFCLOUD_QUICK_START";
void main() {
runApp(const MyApp());
var productSorter = ProductSorter();
productSorter.initializeQuickStart();
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String uiResponse = 'Unknown';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Quick start example app'),
),
body: Center(
child: Text(uiResponse),
),
),
);
}
}
class ProductSorter {
String _datafileHost = "https://cdn.eyeofcloud.com";
String _datafileSuffixAndroid = "/datafiles/%s.json";
String _datafileSuffixIOS = "/datafiles/%@.json";
Future<void> initializeQuickStart() async {
// Setting up custom datafile URL format
Map<ClientPlatform, DatafileHostOptions> datafileHostOptions = {};
datafileHostOptions[ClientPlatform.android] =
DatafileHostOptions(_datafileHost, _datafileSuffixAndroid);
datafileHostOptions[ClientPlatform.iOS] =
DatafileHostOptions(_datafileHost, _datafileSuffixIOS);
// Initializing EyeofcloudClient
var flutterSDK = EyeofcloudFlutterSdk(
sdkKey, datafileHostOptions: datafileHostOptions);
var response = await flutterSDK.initializeClient();
if (response.success) {
flutterSDK.addConfigUpdateNotificationListener((msg) {
runQuickStart(flutterSDK);
});
await runQuickStart(flutterSDK);
}
}
Future<void> runQuickStart(EyeofcloudFlutterSdk flutterSDK) async {
/* --------------------------------
* to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
* --------------------------------
*/
/* --------------------------------
OPTIONAL: Add a notification listener so you can integrate with third-party analytics platforms
--------------------------------
*/
// var notificationId = await flutterSDK.addDecisionNotificationListener((decisionNotification) {
// if (decisionNotification.type == "flag") {
//
// var serializedInfo = decisionNotification.decisionInfo.toString();
// print("$logTag Feature flag access related information: ${serializedInfo}");
// // Send data to analytics provider here
// }
// });
// simulate 50 users
var rangeMax = 9999;
var rangeMin = 1000;
var range = Random();
var hasOnFlags = false;
for (int i = 0; i < 10; i++) {
var userId = "${range.nextInt(rangeMax - rangeMin) + rangeMin}";
/* --------------------------------
Create hardcoded user & bucket user into a flag variation
--------------------------------
*/
var user = await flutterSDK.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
var decisionResponse = await user!.decide("product_sort");
var decision = decisionResponse.decision;
// did decision fail with a critical error?
if (decision?.variationKey == null) {
print("\n\n$logTag decision error: ${decisionResponse.reason}");
}
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
String sortMethod = decision?.variables["sort_method"] as String;
if (decision!.enabled) {
// Keep count how many visitors had the flag enabled
hasOnFlags = true;
}
/* --------------------------------
Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
--------------------------------
*/
// always returns false until you enable a flag rule in your Eyeofcloud project
var userIdResponse = await user.getUserId();
print("\n\n$logTag Flag ${(decision.enabled
? "on"
: "off")}. User number ${userIdResponse.userId} saw flag variation: ${decision
.variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision
.ruleKey}");
await mockPurchase(user);
}
if (!hasOnFlags) {
print(
"\n\n$logTag Flag was off for everyone. Some reasons could include:\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON.\nCheck your key at https://app.eyeofcloud.com/v2/projects/YOUR_PROJECT_ID/settings/implementation");
} else {
}
}
// mock tracking a user event so you can see some experiment reports
Future<void> mockPurchase(EyeofcloudUserContext user) async {
print("\n\n$logTag Pretend that user made a purchase? y/n ");
Random rnd = new Random();
int yesOrNo = rnd.nextInt(2);
// Assigning random yes and no
String answer = yesOrNo == 1? "y" : "n";
print("\n\n$logTag $answer");
var userIdResponse = await user.getUserId();
if (answer == "y") {
// track a user event you defined in the Eyeofcloud app
await user.trackEvent("purchase");
print("\n\n$logTag Eyeofcloud recorded a purchase in experiment results for user ${userIdResponse.userId}");
} else {
print("\n\n$logTag Eyeofcloud didn't record a purchase in experiment results for user ${userIdResponse.userId}");
}
}
}
验证模拟器是否仍在运行。单击在 Android Studio 中运行并回答命令行提示。输出应类似于以下内容:
PowerShell
Flag on. User number 1496 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user made a purchase? y/n
n
Eyeofcloud didn't record a purchase in experiment results for user 1496
Flag off. User number 1194 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 1194
Flag off. User number 5815 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 5815
Flag on. User number 1248 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 1248
Flag off. User number 9580 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user made a purchase? y/n
n
Eyeofcloud didn't record a purchase in experiment results for user 9580
Done with your mocked A/B test.
Check out your report at https://app.eyeofcloud.com/v2/projects/19957465438/reports
Be sure to select the environment that corresponds to your SDK key
// Track how users behave when they see a flag variation
// e.g., after your app processed a purchase, let Eyeofcloud know what happened:
user.trackEvent("purchased");