|
1 | 1 | import 'package:flutter/foundation.dart'; |
2 | | -import 'package:splitio/channel/method_channel_manager.dart'; |
3 | | -import 'package:splitio/events/split_events_listener.dart'; |
4 | | -import 'package:splitio/events/split_method_call_handler.dart'; |
5 | | -import 'package:splitio/split_result.dart'; |
| 2 | +import 'package:splitio_platform_interface/split_result.dart'; |
| 3 | +import 'package:splitio_platform_interface/splitio_platform_interface.dart'; |
6 | 4 |
|
7 | 5 | abstract class SplitClient { |
8 | 6 | /// Performs an evaluation for the [splitName] feature. |
@@ -142,201 +140,157 @@ abstract class SplitClient { |
142 | 140 | } |
143 | 141 |
|
144 | 142 | class DefaultSplitClient implements SplitClient { |
145 | | - static const String _controlTreatment = 'control'; |
146 | | - static const SplitResult _controlResult = |
147 | | - SplitResult(_controlTreatment, null); |
148 | | - |
149 | | - final MethodChannelManager _methodChannelManager; |
150 | | - late final SplitEventMethodCallHandler _methodCallHandler; |
| 143 | + final SplitioPlatform _platform; |
151 | 144 | final String _matchingKey; |
152 | 145 | final String? _bucketingKey; |
153 | 146 |
|
154 | | - late final SplitEventsListener _splitEventsListener; |
155 | | - |
156 | | - DefaultSplitClient( |
157 | | - this._methodChannelManager, this._matchingKey, this._bucketingKey) { |
158 | | - _methodCallHandler = |
159 | | - SplitEventMethodCallHandler(_matchingKey, _bucketingKey, this); |
160 | | - _splitEventsListener = |
161 | | - DefaultEventsListener(_methodChannelManager, _methodCallHandler); |
162 | | - } |
| 147 | + DefaultSplitClient(this._platform, this._matchingKey, this._bucketingKey); |
163 | 148 |
|
164 | 149 | @visibleForTesting |
165 | | - DefaultSplitClient.withEventListener(this._methodChannelManager, |
166 | | - this._matchingKey, this._bucketingKey, this._splitEventsListener); |
| 150 | + DefaultSplitClient.withEventListener( |
| 151 | + this._platform, this._matchingKey, this._bucketingKey); |
167 | 152 |
|
168 | 153 | @override |
169 | 154 | Future<String> getTreatment(String splitName, |
170 | 155 | [Map<String, dynamic> attributes = const {}]) async { |
171 | | - return await _methodChannelManager.invokeMethod( |
172 | | - 'getTreatment', |
173 | | - _buildParameters( |
174 | | - {'splitName': splitName, 'attributes': attributes})) ?? |
175 | | - _controlTreatment; |
| 156 | + return _platform.getTreatment( |
| 157 | + matchingKey: _matchingKey, |
| 158 | + bucketingKey: _bucketingKey, |
| 159 | + splitName: splitName, |
| 160 | + attributes: attributes); |
176 | 161 | } |
177 | 162 |
|
178 | 163 | @override |
179 | 164 | Future<SplitResult> getTreatmentWithConfig(String splitName, |
180 | 165 | [Map<String, dynamic> attributes = const {}]) async { |
181 | | - Map? treatment = (await _methodChannelManager.invokeMapMethod( |
182 | | - 'getTreatmentWithConfig', |
183 | | - _buildParameters( |
184 | | - {'splitName': splitName, 'attributes': attributes}))) |
185 | | - ?.entries |
186 | | - .first |
187 | | - .value; |
188 | | - if (treatment == null) { |
189 | | - return _controlResult; |
190 | | - } |
191 | | - |
192 | | - return SplitResult(treatment['treatment'], treatment['config']); |
| 166 | + return _platform.getTreatmentWithConfig( |
| 167 | + matchingKey: _matchingKey, |
| 168 | + bucketingKey: _bucketingKey, |
| 169 | + splitName: splitName, |
| 170 | + attributes: attributes); |
193 | 171 | } |
194 | 172 |
|
195 | 173 | @override |
196 | 174 | Future<Map<String, String>> getTreatments(List<String> splitNames, |
197 | 175 | [Map<String, dynamic> attributes = const {}]) async { |
198 | | - Map? treatments = await _methodChannelManager.invokeMapMethod( |
199 | | - 'getTreatments', |
200 | | - _buildParameters({'splitName': splitNames, 'attributes': attributes})); |
201 | | - |
202 | | - return treatments |
203 | | - ?.map((key, value) => MapEntry<String, String>(key, value)) ?? |
204 | | - {for (var item in splitNames) item: _controlTreatment}; |
| 176 | + return _platform.getTreatments( |
| 177 | + matchingKey: _matchingKey, |
| 178 | + bucketingKey: _bucketingKey, |
| 179 | + splitNames: splitNames, |
| 180 | + attributes: attributes); |
205 | 181 | } |
206 | 182 |
|
207 | 183 | @override |
208 | 184 | Future<Map<String, SplitResult>> getTreatmentsWithConfig( |
209 | 185 | List<String> splitNames, |
210 | 186 | [Map<String, dynamic> attributes = const {}]) async { |
211 | | - Map? treatments = await _methodChannelManager.invokeMapMethod( |
212 | | - 'getTreatmentsWithConfig', |
213 | | - _buildParameters({'splitName': splitNames, 'attributes': attributes})); |
214 | | - |
215 | | - return treatments?.map((key, value) => |
216 | | - MapEntry(key, SplitResult(value['treatment'], value['config']))) ?? |
217 | | - {for (var item in splitNames) item: _controlResult}; |
| 187 | + return _platform.getTreatmentsWithConfig( |
| 188 | + matchingKey: _matchingKey, |
| 189 | + bucketingKey: _bucketingKey, |
| 190 | + splitNames: splitNames, |
| 191 | + attributes: attributes); |
218 | 192 | } |
219 | 193 |
|
220 | 194 | @override |
221 | 195 | Future<bool> track(String eventType, |
222 | 196 | {String? trafficType, |
223 | 197 | double? value, |
224 | 198 | Map<String, dynamic> properties = const {}}) async { |
225 | | - var parameters = _buildParameters({'eventType': eventType}); |
226 | | - |
227 | | - if (trafficType != null) { |
228 | | - parameters['trafficType'] = trafficType; |
229 | | - } |
230 | | - |
231 | | - if (value != null) { |
232 | | - parameters['value'] = value; |
233 | | - } |
234 | | - |
235 | | - try { |
236 | | - return await _methodChannelManager.invokeMethod("track", parameters) |
237 | | - as bool; |
238 | | - } on Exception catch (_) { |
239 | | - return false; |
240 | | - } |
| 199 | + return _platform.track( |
| 200 | + matchingKey: _matchingKey, |
| 201 | + bucketingKey: _bucketingKey, |
| 202 | + eventType: eventType, |
| 203 | + trafficType: trafficType, |
| 204 | + value: value, |
| 205 | + properties: properties); |
241 | 206 | } |
242 | 207 |
|
243 | 208 | @override |
244 | 209 | Future<bool> setAttribute(String attributeName, dynamic value) async { |
245 | | - var result = await _methodChannelManager.invokeMethod('setAttribute', |
246 | | - _buildParameters({'attributeName': attributeName, 'value': value})); |
247 | | - |
248 | | - if (result is bool) { |
249 | | - return result; |
250 | | - } |
251 | | - |
252 | | - return false; |
| 210 | + return _platform.setAttribute( |
| 211 | + matchingKey: _matchingKey, |
| 212 | + bucketingKey: _bucketingKey, |
| 213 | + attributeName: attributeName, |
| 214 | + value: value); |
253 | 215 | } |
254 | 216 |
|
255 | 217 | @override |
256 | 218 | Future<dynamic> getAttribute(String attributeName) async { |
257 | | - return _methodChannelManager.invokeMethod( |
258 | | - 'getAttribute', _buildParameters({'attributeName': attributeName})); |
| 219 | + return _platform.getAttribute( |
| 220 | + matchingKey: _matchingKey, |
| 221 | + bucketingKey: _bucketingKey, |
| 222 | + attributeName: attributeName); |
259 | 223 | } |
260 | 224 |
|
261 | 225 | @override |
262 | 226 | Future<bool> setAttributes(Map<String, dynamic> attributes) async { |
263 | | - var result = await _methodChannelManager.invokeMethod( |
264 | | - 'setAttributes', _buildParameters({'attributes': attributes})); |
265 | | - |
266 | | - if (result is bool) { |
267 | | - return result; |
268 | | - } |
269 | | - |
270 | | - return false; |
| 227 | + return _platform.setAttributes( |
| 228 | + matchingKey: _matchingKey, |
| 229 | + bucketingKey: _bucketingKey, |
| 230 | + attributes: attributes); |
271 | 231 | } |
272 | 232 |
|
273 | 233 | @override |
274 | 234 | Future<Map<String, dynamic>> getAttributes() async { |
275 | | - return (await _methodChannelManager.invokeMapMethod( |
276 | | - 'getAllAttributes', _buildParameters())) |
277 | | - ?.map((key, value) => MapEntry<String, Object?>(key, value)) ?? |
278 | | - {}; |
| 235 | + return _platform.getAllAttributes( |
| 236 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
279 | 237 | } |
280 | 238 |
|
281 | 239 | @override |
282 | 240 | Future<bool> removeAttribute(String attributeName) async { |
283 | | - return await _methodChannelManager.invokeMethod( |
284 | | - 'removeAttribute', _buildParameters({'attributeName': attributeName})); |
| 241 | + return _platform.removeAttribute( |
| 242 | + matchingKey: _matchingKey, |
| 243 | + bucketingKey: _bucketingKey, |
| 244 | + attributeName: attributeName); |
285 | 245 | } |
286 | 246 |
|
287 | 247 | @override |
288 | 248 | Future<bool> clearAttributes() async { |
289 | | - return await _methodChannelManager.invokeMethod( |
290 | | - 'clearAttributes', _buildParameters()); |
| 249 | + return _platform.clearAttributes( |
| 250 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
291 | 251 | } |
292 | 252 |
|
293 | 253 | @override |
294 | 254 | Future<void> flush() async { |
295 | | - return _methodChannelManager.invokeMethod('flush', _buildParameters()); |
| 255 | + return _platform.flush( |
| 256 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
296 | 257 | } |
297 | 258 |
|
298 | 259 | @override |
299 | 260 | Future<void> destroy() async { |
300 | | - _splitEventsListener.destroy(); |
301 | | - return _methodChannelManager.invokeMethod('destroy', _buildParameters()); |
| 261 | + return _platform.destroy( |
| 262 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
302 | 263 | } |
303 | 264 |
|
304 | 265 | @override |
305 | | - Future<SplitClient> whenReady() { |
306 | | - return _splitEventsListener.onReady(); |
| 266 | + Future<SplitClient> whenReady() async { |
| 267 | + await _platform.onReady( |
| 268 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
| 269 | + |
| 270 | + return Future.value(this); |
307 | 271 | } |
308 | 272 |
|
309 | 273 | @override |
310 | | - Future<SplitClient> whenReadyFromCache() { |
311 | | - return _splitEventsListener.onReadyFromCache(); |
| 274 | + Future<SplitClient> whenReadyFromCache() async { |
| 275 | + await _platform.onReadyFromCache( |
| 276 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
| 277 | + |
| 278 | + return Future.value(this); |
312 | 279 | } |
313 | 280 |
|
314 | 281 | @override |
315 | 282 | Stream<SplitClient> whenUpdated() { |
316 | | - return _splitEventsListener.onUpdated(); |
| 283 | + return _platform |
| 284 | + .onUpdated(matchingKey: _matchingKey, bucketingKey: _bucketingKey) |
| 285 | + ?.map((event) => this) ?? |
| 286 | + const Stream.empty(); |
317 | 287 | } |
318 | 288 |
|
319 | 289 | @override |
320 | | - Future<SplitClient> whenTimeout() { |
321 | | - return _splitEventsListener.onTimeout(); |
322 | | - } |
323 | | - |
324 | | - Map<String, String> _getKeysMap() { |
325 | | - Map<String, String> result = {'matchingKey': _matchingKey}; |
326 | | - |
327 | | - if (_bucketingKey != null) { |
328 | | - result.addAll({'bucketingKey': _bucketingKey!}); |
329 | | - } |
330 | | - |
331 | | - return result; |
332 | | - } |
333 | | - |
334 | | - Map<String, dynamic> _buildParameters( |
335 | | - [Map<String, dynamic> parameters = const {}]) { |
336 | | - Map<String, dynamic> result = {}; |
337 | | - result.addAll(parameters); |
338 | | - result.addAll(_getKeysMap()); |
| 290 | + Future<SplitClient> whenTimeout() async { |
| 291 | + await _platform.onTimeout( |
| 292 | + matchingKey: _matchingKey, bucketingKey: _bucketingKey); |
339 | 293 |
|
340 | | - return result; |
| 294 | + return Future.value(this); |
341 | 295 | } |
342 | 296 | } |
0 commit comments