Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datafile related changes #1

Merged
merged 4 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.policygenius.optimizely_plugin
import android.app.Activity
import androidx.annotation.NonNull
import com.noveogroup.android.log.Log
import com.optimizely.ab.android.sdk.OptimizelyClient
import com.optimizely.ab.android.sdk.OptimizelyManager
import com.optimizely.ab.optimizelyjson.OptimizelyJSON
import io.flutter.embedding.engine.plugins.FlutterPlugin
Expand All @@ -23,7 +24,8 @@ class OptimizelyPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel
private lateinit var activity: Activity
private lateinit var optimizelyManager: OptimizelyManager
//private lateinit var optimizelyManager: OptimizelyManager
private lateinit var optimizelyClient: OptimizelyClient

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "optimizely_plugin")
Expand All @@ -48,23 +50,27 @@ class OptimizelyPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
}

override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "isFeatureEnabled") {
val featureKey = call.argument<String>("feature_key")
val userId = call.argument<String>("user_id")
val flag = isFeatureEnabled(featureKey!!, userId!!)
result.success(flag)
} else if (call.method == "initOptimizelyManager") {
val sdkKey = call.argument<String>("sdk_key")
initOptimizelyManager(sdkKey!!)
result.success("")
} else if (call.method == "getAllFeatureVariables") {
val featureKey = call.argument<String>("feature_key")
val userId = call.argument<String>("user_id")
val attributes = call.argument<MutableMap<String,Any>>("attributes")
val variables = getAllFeatureVariables(featureKey!!,userId!!,attributes!!)
result.success(variables)
} else {
result.notImplemented()
when (call.method) {
"initOptimizelyManager" -> {
val sdkKey = call.argument<String>("sdk_key")
val dataFile = call.argument<String>("datafile")
initOptimizelyManager(sdkKey!!, dataFile!!)
result.success("")
}
"isFeatureEnabled" -> {
val featureKey = call.argument<String>("feature_key")
val userId = call.argument<String>("user_id")
val flag = isFeatureEnabled(featureKey!!, userId!!)
result.success(flag)
}
"getAllFeatureVariables" -> {
val featureKey = call.argument<String>("feature_key")
val userId = call.argument<String>("user_id")
val attributes = call.argument<MutableMap<String,Any>>("attributes")
val variables = getAllFeatureVariables(featureKey!!,userId!!,attributes!!)
result.success(variables)
}
else -> result.notImplemented()
}
}

Expand All @@ -88,34 +94,27 @@ class OptimizelyPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
TODO("Not yet implemented")
}

private fun initOptimizelyManager(sdkKey: String) {
private fun initOptimizelyManager(sdkKey: String, dataFile: String) {
val builder = OptimizelyManager.builder()
// In Android, the minimum polling interval is 60 seconds. In iOS, the minimum polling
// interval is 2 minutes while the app is open. If you specify shorter polling intervals
// than these minimums, the SDK will automatically reset the intervals to 60 seconds (Android)
// or 2 minutes (iOS).
optimizelyManager = builder.withDatafileDownloadInterval(60)
val optimizelyManager = builder.withDatafileDownloadInterval(60)
.withSDKKey(sdkKey)
.build(activity.applicationContext)

optimizelyClient = optimizelyManager.initialize(activity.applicationContext, dataFile, true, true)
}

private fun isFeatureEnabled(featureKey: String, userId: String): Boolean{
// Updated datafiles do not take effect until your app is restarted or when you re-initialize
// the Optimizely manager. This implementation strategy allows the data to change while the
// app is running without causing nondeterministic behavior.
val client = optimizelyManager.initialize(activity.applicationContext, R.raw.datafile)
val flag = client.isFeatureEnabled(featureKey, userId)
val flag = optimizelyClient.isFeatureEnabled(featureKey, userId)

return flag
}

private fun getAllFeatureVariables(featureKey: String, userId: String, attributes: MutableMap<String, Any>): Map<String, Any>? {
// Updated datafiles do not take effect until your app is restarted or when you re-initialize
// the Optimizely manager. This implementation strategy allows the data to change while the
// app is running without causing nondeterministic behavior.
val client = optimizelyManager.initialize(activity.applicationContext, R.raw.datafile)

val json = client.getAllFeatureVariables(featureKey, userId, attributes)
val json = optimizelyClient.getAllFeatureVariables(featureKey, userId, attributes)
return json?.toMap()
}
}
Empty file.
File renamed without changes.
89 changes: 50 additions & 39 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import 'package:optimizely_plugin/optimizely_plugin.dart';

Future<void> main() async {
runApp(MyApp());
await OptimizelyPlugin.initOptimizelyManager('your_optimizely_sdk_key');
// Uses the Optimizely example:
// https://docs.developers.optimizely.com/full-stack/docs/example-datafile
final dataFile = await rootBundle.loadString('assets/datafile.json');
await OptimizelyPlugin.initOptimizelyManager(
'your_optimizely_sdk_key',
dataFile,
);
}

class MyApp extends StatefulWidget {
Expand All @@ -15,29 +21,29 @@ class MyApp extends StatefulWidget {
}

class _MyAppState extends State<MyApp> {
String _flutterFlag = 'unknown';
String _calculator = 'unknown';
String _priceFilterFlag = 'unknown';
String _minPriceVariable = 'unknown';

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

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> getFlutterFlag() async {
String flutterFlag;
Future<void> getPriceFilterFlag() async {
String priceFilterFlag;
// Platform messages may fail, so we use a try/catch PlatformException.
var platform =
Theme.of(context).platform.toString().split('.')[1].toLowerCase();
try {
bool featureEnabled = await OptimizelyPlugin.isFeatureEnabled(
'flutter',
'user@pg.com',
'price_filter',
'user@example.org',
{'platform': platform},
);
flutterFlag = 'flutter feature is $featureEnabled.';
priceFilterFlag = 'price_filter feature is $featureEnabled.';
} on PlatformException catch (e) {
flutterFlag = "Failed to get feature: '${e.message}'.";
priceFilterFlag = "Failed to get feature: '${e.message}'.";
}

// If the widget was removed from the tree while the asynchronous platform
Expand All @@ -46,30 +52,31 @@ class _MyAppState extends State<MyApp> {
if (!mounted) return;

setState(() {
_flutterFlag = flutterFlag;
_priceFilterFlag = priceFilterFlag;
});
}

Future<void> getCalculatorType() async {
String calculator;
Future<void> getPriceFilterMinPrice() async {
String minPriceVariable;
Map<String, dynamic> variables;
var platform =
Theme.of(context).platform.toString().split('.')[1].toLowerCase();
try {
variables = await OptimizelyPlugin.getAllFeatureVariables(
'merlin_operations_calculator',
'user@pg.com',
'price_filter',
'user@example.org',
{'platform': platform},
);
calculator = variables['calc_type'];
int minPrice = variables['min_price'];
minPriceVariable = "min_price variable is: ${minPrice.toString()}.";
} catch (e) {
calculator = "Failed to get calculator type: '$e'.";
minPriceVariable = "Failed to get min_price variable from feature: '$e'.";
}

if (!mounted) return;

setState(() {
_calculator = calculator;
_minPriceVariable = minPriceVariable;
});
}

Expand All @@ -78,29 +85,33 @@ class _MyAppState extends State<MyApp> {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Optimizely example app'),
title: const Text('Optimizely Example App'),
),
body: Column(
children: [
Center(
child: Text(_flutterFlag),
),
RaisedButton(
child: Text('Get Flutter Flag'),
onPressed: () {
getFlutterFlag();
},
),
Center(
child: Text(_calculator),
),
RaisedButton(
child: Text('Get Calculator Type'),
onPressed: () {
getCalculatorType();
},
)
],
body: SafeArea(
child: Column(
children: [
SizedBox(height: 32),
Center(
child: Text(_priceFilterFlag),
),
RaisedButton(
child: Text('Get Price Filter Flag'),
onPressed: () {
getPriceFilterFlag();
},
),
SizedBox(height: 16),
Center(
child: Text(_minPriceVariable),
),
RaisedButton(
child: Text('Get Price Filter Min Price'),
onPressed: () {
getPriceFilterMinPrice();
},
)
],
),
),
),
);
Expand Down
6 changes: 2 additions & 4 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ flutter:
# the material Icons class.
uses-material-design: true

# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
assets:
- assets/datafile.json

# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
Expand Down
2 changes: 1 addition & 1 deletion ios/Classes/SwiftOptimizelyPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class SwiftOptimizelyPlugin: NSObject, FlutterPlugin {
case "initOptimizelyManager":
do {
let sdkKey: String = try arguments.argument(for: "sdk_key")
let dataFile: String? = try arguments.optionalArgument(for: "dataFile")
let dataFile: String? = try arguments.optionalArgument(for: "datafile")
let client = OptimizelyClient(
sdkKey: sdkKey,
periodicDownloadInterval: 60
Expand Down
6 changes: 5 additions & 1 deletion lib/optimizely_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ class OptimizelyPlugin {
static const MethodChannel _channel =
const MethodChannel('optimizely_plugin');

static Future<void> initOptimizelyManager(String sdkKey) async {
static Future<void> initOptimizelyManager(
String sdkKey,
String dataFile,
) async {
await _channel.invokeMethod('initOptimizelyManager', <String, dynamic>{
'sdk_key': sdkKey,
'datafile': dataFile,
});
}

Expand Down
5 changes: 4 additions & 1 deletion test/optimizely_plugin_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ void main() {

test('initOptimizelyManager', () async {
try {
OptimizelyPlugin.initOptimizelyManager('sdkKey');
OptimizelyPlugin.initOptimizelyManager(
'sdkKey',
'dataFile',
);
} on PlatformException catch (error) {
throw error;
}
Expand Down