Skip to content

Commit 69a689c

Browse files
committed
Added activate listener along with unit tests and updated userID to userId.
1 parent e62e8ee commit 69a689c

19 files changed

+314
-74
lines changed

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ protected void createUserContext(ArgumentsParser argumentsParser, @NonNull Resul
157157
return;
158158
}
159159

160-
String userId = argumentsParser.getUserID();
160+
String userId = argumentsParser.getUserId();
161161
Map<String, Object> attributes = argumentsParser.getAttributes();
162162
if (userId == null) {
163163
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyUserContextResponse.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@
2020
import java.util.Map;
2121

2222
public class OptimizelyUserContextResponse {
23-
private final String userID;
23+
private final String userId;
2424

2525
private final Map<String, Object> attributes;
2626

2727
public OptimizelyUserContextResponse(OptimizelyUserContext optimizelyUserContext) {
28-
this.userID = optimizelyUserContext.getUserId();
28+
this.userId = optimizelyUserContext.getUserId();
2929
this.attributes = optimizelyUserContext.getAttributes();
3030
}
3131

32-
public String getUserID() {
33-
return userID;
32+
public String getUserId() {
33+
return userId;
3434
}
3535

3636
public Map<String, Object> getAttributes() {

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static class NotificationType {
4545

4646
public static class RequestParameterKey {
4747
public static final String SDK_KEY = "sdkKey";
48-
public static final String USER_ID = "userID";
48+
public static final String USER_ID = "userId";
4949
public static final String USER_CONTEXT_ID = "userContextId";
5050
public static final String NOTIFICATION_ID = "id";
5151
public static final String NOTIFICATION_TYPE = "type";
@@ -91,14 +91,14 @@ public static class SuccessMessage {
9191

9292
public static class DecisionListenerKeys {
9393
public static final String TYPE = "type";
94-
public static final String USER_ID = "userID";
94+
public static final String USER_ID = "userId";
9595
public static final String ATTRIBUTES = "attributes";
9696
public static final String DECISION_INFO = "decisionInfo";
9797
}
9898

9999
public static class TrackListenerKeys {
100100
public static final String EVENT_KEY = "eventKey";
101-
public static final String USER_ID = "userID";
101+
public static final String USER_ID = "userId";
102102
public static final String ATTRIBUTES = "attributes";
103103
public static final String EVENT_TAGS = "eventTags";
104104
}

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class _MyAppState extends State<MyApp> {
5353
await flutterSDK.addDecisionNotificationListener((notification) {
5454
print("Parsed decision event ....................");
5555
print(notification.type);
56-
print(notification.userID);
56+
print(notification.userId);
5757
print(notification);
5858
print("decide notification received");
5959
});

ios/Classes/HelperClasses/Constants.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct API {
3838

3939
struct NotificationType {
4040
static let track = "track"
41+
static let activate = "activate"
4142
static let decision = "decision"
4243
static let logEvent = "logEvent"
4344
static let projectConfigUpdate = "projectConfigUpdate"
@@ -53,7 +54,7 @@ struct DecideOption {
5354

5455
struct RequestParameterKey {
5556
static let sdkKey = "sdkKey"
56-
static let userId = "userID"
57+
static let userId = "userId"
5758
static let userContextId = "userContextId"
5859
static let notificationId = "id"
5960
static let notificationType = "type"

ios/Classes/HelperClasses/Utils.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,26 @@ public class Utils: NSObject {
8585
return listener
8686
}
8787

88+
/// Returns callback required for ActivateListener
89+
static func getActivateCallback(id: Int) -> ActivateListener {
90+
let listener : ActivateListener = {(experiment, userId, attributes, variation, logEvents) in
91+
let listenerDict : [String : Any] = [
92+
"experiment" : experiment,
93+
"userId" : userId,
94+
"attributes" : attributes as Any,
95+
"variation" : variation
96+
]
97+
SwiftOptimizelyFlutterSdkPlugin.channel.invokeMethod("\(NotificationType.activate)CallbackListener", arguments: [RequestParameterKey.notificationId: id, RequestParameterKey.notificationType: NotificationType.activate, RequestParameterKey.notificationPayload: listenerDict])
98+
}
99+
return listener
100+
}
101+
88102
/// Returns callback required for DecisionListener
89103
static func getDecisionCallback(id: Int) -> DecisionListener {
90104
let listener : DecisionListener = {(type, userId, attributes, decisionInfo) in
91105
let listenerDict : [String : Any] = [
92106
"type" : type,
93-
"userID" : userId,
107+
"userId" : userId,
94108
"attributes" : attributes as Any,
95109
"decisionInfo": decisionInfo
96110
]
@@ -106,7 +120,7 @@ public class Utils: NSObject {
106120
"attributes" : attributes as Any,
107121
"eventKey" : eventKey,
108122
"eventTags" : eventTags as Any,
109-
"userID" : userId,
123+
"userId" : userId,
110124
// "event": event as Any, This is causing codec related exceptions on flutter side, need to debug
111125
]
112126
SwiftOptimizelyFlutterSdkPlugin.channel.invokeMethod("\(NotificationType.track)CallbackListener", arguments: [RequestParameterKey.notificationId: id, RequestParameterKey.notificationType: NotificationType.track, RequestParameterKey.notificationPayload: listenerDict])

ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,30 +133,28 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
133133
result(createResponse(success: false, reason: ErrorMessage.invalidParameters))
134134
return
135135
}
136+
var notificationId = 0
136137
switch type {
138+
case NotificationType.activate:
139+
notificationId = (optimizelyClient.notificationCenter?.addActivateNotificationListener(activateListener: Utils.getActivateCallback(id: id)))!
137140
case NotificationType.decision:
138-
let notificationId = optimizelyClient.notificationCenter?.addDecisionNotificationListener(decisionListener: Utils.getDecisionCallback(id: id))!
139-
notificationIdsTracker[id] = notificationId
140-
result(self.createResponse(success: true, reason: SuccessMessage.listenerAdded))
141+
notificationId = (optimizelyClient.notificationCenter?.addDecisionNotificationListener(decisionListener: Utils.getDecisionCallback(id: id)))!
141142
break
142143
case NotificationType.track:
143-
let notificationId = optimizelyClient.notificationCenter?.addTrackNotificationListener(trackListener: Utils.getTrackCallback(id: id))
144-
notificationIdsTracker[id] = notificationId
145-
result(self.createResponse(success: true, reason: SuccessMessage.listenerAdded))
144+
notificationId = (optimizelyClient.notificationCenter?.addTrackNotificationListener(trackListener: Utils.getTrackCallback(id: id)))!
146145
break
147146
case NotificationType.logEvent:
148-
let notificationId = optimizelyClient.notificationCenter?.addLogEventNotificationListener(logEventListener: Utils.getLogEventCallback(id: id))
149-
notificationIdsTracker[id] = notificationId
150-
result(self.createResponse(success: true, reason: SuccessMessage.listenerAdded))
147+
notificationId = (optimizelyClient.notificationCenter?.addLogEventNotificationListener(logEventListener: Utils.getLogEventCallback(id: id)))!
151148
break
152149
case NotificationType.projectConfigUpdate:
153150
let notificationId = optimizelyClient.notificationCenter?.addDatafileChangeNotificationListener(datafileListener: Utils.getProjectConfigUpdateCallback(id: id))
154-
notificationIdsTracker[id] = notificationId
155-
result(self.createResponse(success: true, reason: SuccessMessage.listenerAdded))
156151
break
157152
default:
158153
result(createResponse(success: false, reason: ErrorMessage.invalidParameters))
154+
return
159155
}
156+
notificationIdsTracker[id] = notificationId
157+
result(self.createResponse(success: true, reason: SuccessMessage.listenerAdded))
160158
}
161159

162160
/// Removes notification listeners from the optimizely client as requested

lib/optimizely_flutter_sdk.dart

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
library optimizely_flutter_sdk;
1818

1919
import 'dart:async';
20+
import 'package:optimizely_flutter_sdk/src/data_objects/activate_response.dart';
2021
import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
2122
import 'package:optimizely_flutter_sdk/src/data_objects/datafile_options.dart';
2223
import 'package:optimizely_flutter_sdk/src/data_objects/event_options.dart';
2324
import 'package:optimizely_flutter_sdk/src/data_objects/get_forced_decision_response.dart';
25+
import 'package:optimizely_flutter_sdk/src/data_objects/get_variation_response.dart';
2426
import 'package:optimizely_flutter_sdk/src/data_objects/optimizely_config_response.dart';
2527
import 'package:optimizely_flutter_sdk/src/optimizely_client_wrapper.dart';
2628
import 'package:optimizely_flutter_sdk/src/user_context/optimizely_user_context.dart';
@@ -78,16 +80,14 @@ class OptimizelyFlutterSdk {
7880
/// The activate call will conditionally activate an experiment for a user based on the provided experiment key and a randomized hash of the provided user ID.
7981
/// If the user satisfies audience conditions for the experiment and the experiment is valid and running, the function returns the variation the user is bucketed into.
8082
/// Otherwise, activate returns empty variationKey. Make sure that your code adequately deals with the case when the experiment is not activated (e.g. execute the default variation).
81-
Future<GetForcedDecisionResponse> activate(
82-
String experimentKey, String userId,
83+
Future<ActivateResponse> activate(String experimentKey, String userId,
8384
[Map<String, dynamic> attributes = const {}]) async {
8485
return await OptimizelyClientWrapper.activate(
8586
_sdkKey, experimentKey, userId, attributes);
8687
}
8788

8889
/// Get variation for experiment and user ID with user attributes.
89-
Future<GetForcedDecisionResponse> getVariation(
90-
String experimentKey, String userId,
90+
Future<GetVariationResponse> getVariation(String experimentKey, String userId,
9191
[Map<String, dynamic> attributes = const {}]) async {
9292
return await OptimizelyClientWrapper.getVariation(
9393
_sdkKey, experimentKey, userId, attributes);
@@ -112,24 +112,41 @@ class OptimizelyFlutterSdk {
112112
return await OptimizelyClientWrapper.close(_sdkKey);
113113
}
114114

115+
/// Allows user to listen to supported Activate notifications.
116+
Future<CancelListening> addActivateNotificationListener(
117+
ActivateNotificationCallback callback) async {
118+
return await _addActivateNotificationListener(callback);
119+
}
120+
121+
/// Allows user to listen to supported Decision notifications.
115122
Future<CancelListening> addDecisionNotificationListener(
116123
DecisionNotificationCallback callback) async {
117124
return await _addDecisionNotificationListener(callback);
118125
}
119126

127+
/// Allows user to listen to supported Track notifications.
120128
Future<CancelListening> addTrackNotificationListener(
121129
TrackNotificationCallback callback) async {
122130
return await _addTrackNotificationListener(callback);
123131
}
124132

133+
/// Allows user to listen to supported LogEvent notifications.
134+
Future<CancelListening> addLogEventNotificationListener(
135+
LogEventNotificationCallback callback) async {
136+
return await _addLogEventNotificationListener(callback);
137+
}
138+
139+
/// Allows user to listen to supported Project Config Update notifications.
125140
Future<CancelListening> addUpdateConfigNotificationListener(
126141
MultiUseCallback callback) async {
127142
return await _addConfigUpdateNotificationListener(callback);
128143
}
129144

130-
Future<CancelListening> addLogEventNotificationListener(
131-
LogEventNotificationCallback callback) async {
132-
return await _addLogEventNotificationListener(callback);
145+
/// Allows user to listen to supported Activate notifications.
146+
Future<CancelListening> _addActivateNotificationListener(
147+
ActivateNotificationCallback callback) async {
148+
return await OptimizelyClientWrapper.addActivateNotificationListener(
149+
_sdkKey, callback);
133150
}
134151

135152
/// Allows user to listen to supported Decision notifications.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// **************************************************************************
2+
/// Copyright 2022, Optimizely, Inc. and contributors *
3+
/// *
4+
/// Licensed under the Apache License, Version 2.0 (the "License"); *
5+
/// you may not use this file except in compliance with the License. *
6+
/// You may obtain a copy of the License at *
7+
/// *
8+
/// http://www.apache.org/licenses/LICENSE-2.0 *
9+
/// *
10+
/// Unless required by applicable law or agreed to in writing, software *
11+
/// distributed under the License is distributed on an "AS IS" BASIS, *
12+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
/// See the License for the specific language governing permissions and *
14+
/// limitations under the License. *
15+
///**************************************************************************/
16+
17+
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
18+
19+
class ActivateListenerResponse {
20+
String userId = '';
21+
Map<String, dynamic> attributes = {};
22+
Map<String, dynamic> experiment = {};
23+
Map<String, dynamic> variation = {};
24+
25+
ActivateListenerResponse(Map<String, dynamic> json) {
26+
if (json[Constants.userId] is String) {
27+
userId = json[Constants.userId];
28+
}
29+
30+
if (json[Constants.attributes] is Map<dynamic, dynamic>) {
31+
attributes = Map<String, dynamic>.from(json[Constants.attributes]);
32+
}
33+
34+
if (json[Constants.experiment] is Map<dynamic, dynamic>) {
35+
experiment = Map<String, dynamic>.from(json[Constants.experiment]);
36+
}
37+
38+
if (json[Constants.variation] is Map<dynamic, dynamic>) {
39+
variation = Map<String, dynamic>.from(json[Constants.variation]);
40+
}
41+
}
42+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/// **************************************************************************
2+
/// Copyright 2022, Optimizely, Inc. and contributors *
3+
/// *
4+
/// Licensed under the Apache License, Version 2.0 (the "License"); *
5+
/// you may not use this file except in compliance with the License. *
6+
/// You may obtain a copy of the License at *
7+
/// *
8+
/// http://www.apache.org/licenses/LICENSE-2.0 *
9+
/// *
10+
/// Unless required by applicable law or agreed to in writing, software *
11+
/// distributed under the License is distributed on an "AS IS" BASIS, *
12+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
/// See the License for the specific language governing permissions and *
14+
/// limitations under the License. *
15+
///**************************************************************************/
16+
17+
import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
18+
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
19+
20+
class ActivateResponse extends BaseResponse {
21+
String variationKey = '';
22+
23+
ActivateResponse(Map<String, dynamic> json) : super(json) {
24+
if (json[Constants.responseResult] is Map<dynamic, dynamic>) {
25+
var response = Map<String, dynamic>.from(json[Constants.responseResult]);
26+
if (response[Constants.variationKey] is String) {
27+
variationKey = response[Constants.variationKey];
28+
}
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)