From 0f4a6ebf5de9a3f819ae76992e0a9db15f38a63c Mon Sep 17 00:00:00 2001 From: Jae Kim <45045038+jaeopt@users.noreply.github.com> Date: Wed, 10 Jan 2024 08:52:45 -0800 Subject: [PATCH 01/12] fix proguard for logback and dart version (#68) --- android/proguard-rules.txt | 3 ++- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android/proguard-rules.txt b/android/proguard-rules.txt index 7fede45..1564ced 100644 --- a/android/proguard-rules.txt +++ b/android/proguard-rules.txt @@ -10,5 +10,6 @@ # Optimizely -keep class com.optimizely.optimizely_flutter_sdk.** {*;} -keep class com.fasterxml.jackson.** {*;} +# Logback +-keep class ch.qos.** { *; } ##---------------End: proguard configuration ---------- - diff --git a/pubspec.yaml b/pubspec.yaml index c2f0293..bda345b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 2.0.0-beta homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: - sdk: '>=2.16.2 <=3.1.2' + sdk: '>=2.16.2 <4.0.0' flutter: ">=2.5.0" dependencies: From ea0fdc40c20743e59d5126b37a6a9a501347a7eb Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Tue, 23 Jan 2024 23:19:35 +0600 Subject: [PATCH 02/12] [FSSDK-8713] chore: prepare for the release 2.0.0 (#70) * Update version * Update CHANGELOG.md * Update README.md --- CHANGELOG.md | 18 ++++++++++++++++++ README.md | 4 ++-- android/build.gradle | 2 +- example/android/build.gradle | 2 +- ios/optimizely_flutter_sdk.podspec | 2 +- pubspec.yaml | 2 +- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b07c65b..8aa48a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Optimizely Flutter SDK Changelog +## 2.0.0 +January 23, 2024 + +### New Features + +* Add ODP for iOS ([#52](https://github.com/optimizely/optimizely-flutter-sdk/pull/52)). +* Add ODP for Android ([#57](https://github.com/optimizely/optimizely-flutter-sdk/pull/57)). + +### Bug Fixes + +* Crash fixed, fetchQualifiedSegments without options ([#64](https://github.com/optimizely/optimizely-flutter-sdk/pull/64)). +* Fix proguard for logback and dart version ([#68](https://github.com/optimizely/optimizely-flutter-sdk/pull/68)). + +### Functionality Enhancements + +* Update Github Issue Templates ([#65](https://github.com/optimizely/optimizely-flutter-sdk/pull/65)). +* Add configurable log level support ([#63](https://github.com/optimizely/optimizely-flutter-sdk/pull/63)). + ## 2.0.0-beta September 21, 2023 diff --git a/README.md b/README.md index e8a6edf..c0a2205 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ See the [pubspec.yaml](https://github.com/optimizely/optimizely-flutter-sdk/blob On the Android platform, the SDK requires a minimum SDK version of 21 or higher and compile SDK version of 32. -On the iOS platform, the SDK requires a minimum version of 10.0. +On the iOS platform, the SDK requires a minimum version of 11.0. Other Flutter platforms are not currently supported by this SDK. @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^1.0.1 + optimizely_flutter_sdk: ^2.0.0 ``` Then run diff --git a/android/build.gradle b/android/build.gradle index 03427ea..9934507 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -83,7 +83,7 @@ dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:4.0.0-beta2" + implementation "com.optimizely.ab:android-sdk:4.0.0" implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/example/android/build.gradle b/example/android/build.gradle index c133c66..58051f6 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -11,7 +11,7 @@ buildscript { } } ext { - android_sdk_version = "4.0.0-beta3" + android_sdk_version = "4.0.0" } allprojects { repositories { diff --git a/ios/optimizely_flutter_sdk.podspec b/ios/optimizely_flutter_sdk.podspec index 2a528d5..4da4408 100644 --- a/ios/optimizely_flutter_sdk.podspec +++ b/ios/optimizely_flutter_sdk.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'OptimizelySwiftSDK', '4.0.0-beta' + s.dependency 'OptimizelySwiftSDK', '4.0.0' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/pubspec.yaml b/pubspec.yaml index bda345b..7ffd848 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 2.0.0-beta +version: 2.0.0 homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: From 52b49ce1dba0372b395a33edb597d64d06a60f8a Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:16:46 +0600 Subject: [PATCH 03/12] Revert "[FSSDK-8713] chore: prepare for the release 2.0.0" (#71) --- CHANGELOG.md | 18 ------------------ README.md | 4 ++-- android/build.gradle | 2 +- example/android/build.gradle | 2 +- ios/optimizely_flutter_sdk.podspec | 2 +- pubspec.yaml | 2 +- 6 files changed, 6 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aa48a2..b07c65b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,5 @@ # Optimizely Flutter SDK Changelog -## 2.0.0 -January 23, 2024 - -### New Features - -* Add ODP for iOS ([#52](https://github.com/optimizely/optimizely-flutter-sdk/pull/52)). -* Add ODP for Android ([#57](https://github.com/optimizely/optimizely-flutter-sdk/pull/57)). - -### Bug Fixes - -* Crash fixed, fetchQualifiedSegments without options ([#64](https://github.com/optimizely/optimizely-flutter-sdk/pull/64)). -* Fix proguard for logback and dart version ([#68](https://github.com/optimizely/optimizely-flutter-sdk/pull/68)). - -### Functionality Enhancements - -* Update Github Issue Templates ([#65](https://github.com/optimizely/optimizely-flutter-sdk/pull/65)). -* Add configurable log level support ([#63](https://github.com/optimizely/optimizely-flutter-sdk/pull/63)). - ## 2.0.0-beta September 21, 2023 diff --git a/README.md b/README.md index c0a2205..e8a6edf 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ See the [pubspec.yaml](https://github.com/optimizely/optimizely-flutter-sdk/blob On the Android platform, the SDK requires a minimum SDK version of 21 or higher and compile SDK version of 32. -On the iOS platform, the SDK requires a minimum version of 11.0. +On the iOS platform, the SDK requires a minimum version of 10.0. Other Flutter platforms are not currently supported by this SDK. @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^2.0.0 + optimizely_flutter_sdk: ^1.0.1 ``` Then run diff --git a/android/build.gradle b/android/build.gradle index 9934507..03427ea 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -83,7 +83,7 @@ dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:4.0.0" + implementation "com.optimizely.ab:android-sdk:4.0.0-beta2" implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/example/android/build.gradle b/example/android/build.gradle index 58051f6..c133c66 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -11,7 +11,7 @@ buildscript { } } ext { - android_sdk_version = "4.0.0" + android_sdk_version = "4.0.0-beta3" } allprojects { repositories { diff --git a/ios/optimizely_flutter_sdk.podspec b/ios/optimizely_flutter_sdk.podspec index 4da4408..2a528d5 100644 --- a/ios/optimizely_flutter_sdk.podspec +++ b/ios/optimizely_flutter_sdk.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'OptimizelySwiftSDK', '4.0.0' + s.dependency 'OptimizelySwiftSDK', '4.0.0-beta' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/pubspec.yaml b/pubspec.yaml index 7ffd848..bda345b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 2.0.0 +version: 2.0.0-beta homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: From 5521cc9a7e2e1d4b103bb64e5bf4a0b7662fc515 Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Fri, 26 Jan 2024 18:45:31 +0600 Subject: [PATCH 04/12] [FSSDK-9358] chore: add flutter specific client name support to track event (#72) * Client depedency updated to 4.0.0 * PlatformService ready for clinet name * SDK client name and version injectecd to native SDK * Package info added * Remove unused code and file * clean up * Test case added * Clean up --- android/build.gradle | 2 +- .../OptimizelyFlutterClient.java | 5 +- .../helper_classes/ArgumentsParser.java | 4 + .../helper_classes/Constants.java | 1 + .../helper_classes/Utils.java | 3 +- example/android/build.gradle | 2 +- ios/Classes/HelperClasses/Constants.swift | 1 + ios/Classes/HelperClasses/Utils.swift | 2 +- .../SwiftOptimizelyFlutterSdkPlugin.swift | 5 +- ios/optimizely_flutter_sdk.podspec | 2 +- lib/package_info.dart | 7 ++ lib/src/optimizely_client_wrapper.dart | 4 + lib/src/utils/constants.dart | 1 + lib/src/utils/utils.dart | 2 +- test/optimizely_flutter_sdk_test.dart | 76 ++++++++++++++++++- test/test_utils.dart | 35 +++++++++ 16 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 lib/package_info.dart diff --git a/android/build.gradle b/android/build.gradle index 03427ea..9934507 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -83,7 +83,7 @@ dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:4.0.0-beta2" + implementation "com.optimizely.ab:android-sdk:4.0.0" implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java index 82e3384..c571c2f 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java @@ -78,6 +78,8 @@ public class OptimizelyFlutterClient { protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @NonNull Result result) { String sdkKey = argumentsParser.getSdkKey(); + String sdkName = Utils.sdkName; + String sdkVersion = argumentsParser.getSdkVersion(); if (sdkKey == null) { result.success(createResponse(ErrorMessage.INVALID_PARAMS)); return; @@ -172,7 +174,8 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N .withODPSegmentCacheTimeout(segmentsCacheTimeoutInSecs, TimeUnit.SECONDS) .withTimeoutForODPSegmentFetch(timeoutForSegmentFetchInSecs) .withTimeoutForODPEventDispatch(timeoutForOdpEventInSecs) - .withSDKKey(sdkKey); + .withSDKKey(sdkKey) + .withClientInfo(sdkName, sdkVersion); if (disableOdp) { optimizelyManagerBuilder.withODPDisabled(); } diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java index 88087c7..6d2741f 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java @@ -31,6 +31,10 @@ public ArgumentsParser(Map arguments) { public String getSdkKey() { return (String) arguments.get(Constants.RequestParameterKey.SDK_KEY); } + + public String getSdkVersion() { + return (String) arguments.get(Constants.RequestParameterKey.SDK_VERSION); + } public Integer getNotificationID() { return (Integer) arguments.get(Constants.RequestParameterKey.NOTIFICATION_ID); diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java index 453b1d6..0c73d32 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java @@ -58,6 +58,7 @@ public static class NotificationType { public static class RequestParameterKey { public static final String SDK_KEY = "sdkKey"; + public static final String SDK_VERSION = "sdkVersion"; public static final String USER_ID = "userId"; public static final String USER_CONTEXT_ID = "userContextId"; public static final String NOTIFICATION_ID = "id"; diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java index b3020f1..ba4e5a4 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java @@ -37,7 +37,8 @@ import ch.qos.logback.classic.Logger; public class Utils { - + public static String sdkName = "flutter/android-sdk"; + public static String getRandomUUID() { return UUID.randomUUID().toString(); } diff --git a/example/android/build.gradle b/example/android/build.gradle index c133c66..58051f6 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -11,7 +11,7 @@ buildscript { } } ext { - android_sdk_version = "4.0.0-beta3" + android_sdk_version = "4.0.0" } allprojects { repositories { diff --git a/ios/Classes/HelperClasses/Constants.swift b/ios/Classes/HelperClasses/Constants.swift index e5be618..f3ca6d5 100644 --- a/ios/Classes/HelperClasses/Constants.swift +++ b/ios/Classes/HelperClasses/Constants.swift @@ -114,6 +114,7 @@ struct RequestParameterKey { static let timeoutForSegmentFetchInSecs = "timeoutForSegmentFetchInSecs" static let timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs" static let disableOdp = "disableOdp" + static let sdkVersion = "sdkVersion"; } struct ResponseKey { diff --git a/ios/Classes/HelperClasses/Utils.swift b/ios/Classes/HelperClasses/Utils.swift index 6cac144..41b39c1 100644 --- a/ios/Classes/HelperClasses/Utils.swift +++ b/ios/Classes/HelperClasses/Utils.swift @@ -18,7 +18,7 @@ import Foundation import Optimizely public class Utils: NSObject { - + static var sdkName = "flutter/swift-sdk" /// Converts and returns dart map to native map static func getTypedMap(arguments: Any?) -> [String: Any]? { guard let args = arguments as? Dictionary else { diff --git a/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift b/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift index 287b056..8a2fd75 100644 --- a/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift @@ -118,6 +118,9 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { var timeoutForSegmentFetchInSecs: Int = 10 var timeoutForOdpEventInSecs: Int = 10 var disableOdp: Bool = false + var sdkVersion = parameters[RequestParameterKey.sdkVersion] as? String + var sdkName = Utils.sdkName + if let sdkSettings = parameters[RequestParameterKey.optimizelySdkSettings] as? Dictionary { if let cacheSize = sdkSettings[RequestParameterKey.segmentsCacheSize] as? Int { segmentsCacheSize = cacheSize @@ -135,7 +138,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { disableOdp = isOdpDisabled } } - let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp) + let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, sdkName: sdkName, sdkVersion: sdkVersion) // Datafile Download Interval var datafilePeriodicDownloadInterval = 10 * 60 // seconds diff --git a/ios/optimizely_flutter_sdk.podspec b/ios/optimizely_flutter_sdk.podspec index 2a528d5..4da4408 100644 --- a/ios/optimizely_flutter_sdk.podspec +++ b/ios/optimizely_flutter_sdk.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'OptimizelySwiftSDK', '4.0.0-beta' + s.dependency 'OptimizelySwiftSDK', '4.0.0' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/lib/package_info.dart b/lib/package_info.dart new file mode 100644 index 0000000..4c8df19 --- /dev/null +++ b/lib/package_info.dart @@ -0,0 +1,7 @@ +// Purpose: Package information for the Optimizely Flutter SDK +// Note: This info should be synced with pubspec.yaml + +class PackageInfo { + static const String name = 'optimizely_flutter_sdk'; + static const String version = '2.0.0-beta'; +} \ No newline at end of file diff --git a/lib/src/optimizely_client_wrapper.dart b/lib/src/optimizely_client_wrapper.dart index f96ad24..590d17c 100644 --- a/lib/src/optimizely_client_wrapper.dart +++ b/lib/src/optimizely_client_wrapper.dart @@ -18,6 +18,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:optimizely_flutter_sdk/optimizely_flutter_sdk.dart'; +import 'package:optimizely_flutter_sdk/package_info.dart'; import 'package:optimizely_flutter_sdk/src/data_objects/activate_listener_response.dart'; import 'package:optimizely_flutter_sdk/src/data_objects/activate_response.dart'; import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart'; @@ -66,8 +67,11 @@ class OptimizelyClientWrapper { _channel.setMethodCallHandler(methodCallHandler); final convertedOptions = Utils.convertDecideOptions(defaultDecideOptions); final convertedLogLevel = Utils.convertLogLevel(defaultLogLevel); + final sdkVersion = PackageInfo.version; + Map requestDict = { Constants.sdkKey: sdkKey, + Constants.sdkVersion: sdkVersion, Constants.datafilePeriodicDownloadInterval: datafilePeriodicDownloadInterval, Constants.optimizelyDecideOption: convertedOptions, diff --git a/lib/src/utils/constants.dart b/lib/src/utils/constants.dart index d5bc3ff..7ef9547 100644 --- a/lib/src/utils/constants.dart +++ b/lib/src/utils/constants.dart @@ -58,6 +58,7 @@ class Constants { // Request parameter keys static const String id = "id"; static const String sdkKey = "sdkKey"; + static const String sdkVersion = "sdkVersion"; static const String userContextId = "userContextId"; static const String userContext = "userContext"; static const String experiment = "experiment"; diff --git a/lib/src/utils/utils.dart b/lib/src/utils/utils.dart index 782178e..8b18b13 100644 --- a/lib/src/utils/utils.dart +++ b/lib/src/utils/utils.dart @@ -15,7 +15,6 @@ ///**************************************************************************/ import 'dart:io' show Platform; - import 'package:optimizely_flutter_sdk/src/user_context/optimizely_user_context.dart'; import 'package:optimizely_flutter_sdk/src/utils/constants.dart'; import 'package:optimizely_flutter_sdk/src/data_objects/log_level.dart'; @@ -101,4 +100,5 @@ class Utils { // OptimizelyLogLevel.debug -> "debug" return logLevel.toString().split('.').last; } + } diff --git a/test/optimizely_flutter_sdk_test.dart b/test/optimizely_flutter_sdk_test.dart index debf769..dd6bd7a 100644 --- a/test/optimizely_flutter_sdk_test.dart +++ b/test/optimizely_flutter_sdk_test.dart @@ -23,7 +23,6 @@ import 'package:optimizely_flutter_sdk/src/utils/constants.dart'; import 'package:optimizely_flutter_sdk/src/utils/utils.dart'; import 'dart:io'; import 'dart:convert'; - import 'test_utils.dart'; void main() { @@ -557,7 +556,8 @@ void main() { }); test("with a valid defaultLogLevel parameter", () async { - var sdk = OptimizelyFlutterSdk(testSDKKey, defaultLogLevel: OptimizelyLogLevel.debug); + var sdk = OptimizelyFlutterSdk(testSDKKey, + defaultLogLevel: OptimizelyLogLevel.debug); var response = await sdk.initializeClient(); @@ -1553,4 +1553,76 @@ void main() { }); }); }); + + group("Test client_name and client_version event parsing", () { + test("Test track event with swift sdk name and version", () async { + var sdk = OptimizelyFlutterSdk(testSDKKey); + + TrackListenerResponse? response; + + await sdk.addTrackNotificationListener((msg) { + response = msg; + }); + var callHandler = OptimizelyClientWrapper.methodCallHandler; + tester?.setMockMethodCallHandler(channel, callHandler); + TestUtils.sendTestTrackClientNameAndVersion( + callHandler, 0, testSDKKey, "flutter/swift-sdk", "2.0.0"); + + expect(response == null, false); + + expect(response!.eventTags!["client_name"], "flutter/swift-sdk"); + + }); + + test("Test track event with android sdk name and version", () async { + var sdk = OptimizelyFlutterSdk(testSDKKey); + + var responses = []; + + await sdk.addTrackNotificationListener((msg) { + responses.add(msg); + }); + + var callHandler = OptimizelyClientWrapper.methodCallHandler; + tester?.setMockMethodCallHandler(channel, callHandler); + + TestUtils.sendTestTrackClientNameAndVersion( + callHandler, 0, testSDKKey, "flutter/swift-sdk", "2.0.0"); + TestUtils.sendTestTrackClientNameAndVersion( + callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0-beta"); + + expect(responses.length == 2, true); + + expect(responses[0]!.eventTags!["client_name"], "flutter/swift-sdk"); + expect(responses[0]!.eventTags!["client_version"], "2.0.0"); + expect(responses[1]!.eventTags!["client_name"], "flutter/android-sdk"); + expect(responses[1]!.eventTags!["client_version"], "2.0.0-beta"); + + }); + + test("Test log event with client sdk name and version", () async { + var sdk = OptimizelyFlutterSdk(testSDKKey); + + var responses = []; + + await sdk.addLogEventNotificationListener((msg) { + responses.add(msg); + }); + var callHandler = OptimizelyClientWrapper.methodCallHandler; + tester?.setMockMethodCallHandler(channel, callHandler); + TestUtils.sendTestClientNameAndVersionLogEventNotification( + callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0-beta"); + + TestUtils.sendTestClientNameAndVersionLogEventNotification( + callHandler, 0, testSDKKey, "flutter/swift-sdk", "2.0.0"); + + expect(responses.length == 2, true); + + expect(responses[0]!.params!["client_name"], "flutter/android-sdk"); + expect(responses[0]!.params!["client_version"], "2.0.0-beta"); + expect(responses[1]!.params!["client_name"], "flutter/swift-sdk"); + expect(responses[1]!.params!["client_version"], "2.0.0"); + }); + + }); } diff --git a/test/test_utils.dart b/test/test_utils.dart index e08eb73..986bd8e 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -106,6 +106,23 @@ class TestUtils { })); } + static sendTestClientNameAndVersionLogEventNotification( + Function(MethodCall message) handler, int id, String sdkKey, String clientName, String sdkVersion) { + var payload = { + Constants.url: "$id", + Constants.params: { + "test": id, + "client_name": clientName, + "client_version": sdkVersion + } + }; + handler(MethodCall(Constants.logEventCallbackListener, { + Constants.id: id, + Constants.sdkKey: sdkKey, + Constants.payload: payload + })); + } + static sendTestTrackNotifications( Function(MethodCall message) handler, int id, String sdkKey) { var payload = { @@ -121,6 +138,24 @@ class TestUtils { })); } + static sendTestTrackClientNameAndVersion(Function(MethodCall message) handler, int id, String sdkKey, String clientName, String sdkVersion) { + var payload = { + Constants.eventKey: "$id", + Constants.userId: "test", + Constants.attributes: {"test": id}, + Constants.eventTags: { + "testTag": id, + "client_name": clientName, + "client_version": sdkVersion + } + }; + handler(MethodCall(Constants.trackCallBackListener, { + Constants.id: id, + Constants.sdkKey: sdkKey, + Constants.payload: payload + })); + } + static sendTestUpdateConfigNotifications( Function(MethodCall message) handler, int id, String sdkKey) { handler(MethodCall(Constants.configUpdateCallBackListener, { From eec8fdb9a25d85627d66360c1e8741c0d8760079 Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Mon, 29 Jan 2024 19:19:11 +0600 Subject: [PATCH 05/12] [FSSDK-8713] chore: prepare for release 2.0.0 (#73) * Update package_info.dart * Update pubspec.yaml * Update README.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * clean up --- CHANGELOG.md | 51 +++++++++++++++++++++++++++ README.md | 2 +- lib/package_info.dart | 4 +-- pubspec.yaml | 2 +- test/optimizely_flutter_sdk_test.dart | 8 ++--- 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b07c65b..0e77038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,56 @@ # Optimizely Flutter SDK Changelog +## 2.0.0 +January 23, 2024 + +### New Features + +The 2.0.0 release introduces a new primary feature, [Advanced Audience Targeting]( https://docs.developers.optimizely.com/feature-experimentation/docs/optimizely-data-platform-advanced-audience-targeting) enabled through integration with [Optimizely Data Platform (ODP)](https://docs.developers.optimizely.com/optimizely-data-platform/docs) ([#52](https://github.com/optimizely/optimizely-flutter-sdk/pull/52), [#57](https://github.com/optimizely/optimizely-flutter-sdk/pull/57), [#72](https://github.com/optimizely/optimizely-flutter-sdk/pull/72)). + +You can use ODP, a high-performance [Customer Data Platform (CDP)]( https://www.optimizely.com/optimization-glossary/customer-data-platform/), to easily create complex real-time segments (RTS) using first-party and 50+ third-party data sources out of the box. You can create custom schemas that support the user attributes important for your business, and stitch together user behavior done on different devices to better understand and target your customers for personalized user experiences. ODP can be used as a single source of truth for these segments in any Optimizely or 3rd party tool. + +With ODP accounts integrated into Optimizely projects, you can build audiences using segments pre-defined in ODP. The SDK will fetch the segments for given users and make decisions using the segments. For access to ODP audience targeting in your Feature Experimentation account, please contact your Customer Success Manager. + +This version includes the following changes: + +* New API added to `OptimizelyUserContext`: + + - `fetchQualifiedSegments()`: this API will retrieve user segments from the ODP server. The fetched segments will be used for audience evaluation. The fetched data will be stored in the local cache to avoid repeated network delays. + + - When an `OptimizelyUserContext` is created, the SDK will automatically send an identify request to the ODP server to facilitate observing user activities. + +* New APIs added to `OptimizelyFlutterSdk`: + + - `sendOdpEvent()`: customers can build/send arbitrary ODP events that will bind user identifiers and data to user profiles in ODP. + + - `createUserContext()` with anonymous user IDs: user-contexts can be created without a userId. The SDK will create and use a persistent `VUID` specific to a device when userId is not provided. + +For details, refer to our documentation pages: + +* [Advanced Audience Targeting](https://docs.developers.optimizely.com/feature-experimentation/docs/optimizely-data-platform-advanced-audience-targeting) + +* [Client SDK Support](https://docs.developers.optimizely.com/feature-experimentation/v1.0/docs/advanced-audience-targeting-for-client-side-sdks) + +* [Initialize Flutter SDK](https://docs.developers.optimizely.com/feature-experimentation/docs/initialize-sdk-flutter) + +* [OptimizelyUserContext Flutter SDK](https://docs.developers.optimizely.com/feature-experimentation/docs/optimizelyusercontext-flutter) + +* [Advanced Audience Targeting segment qualification methods](https://docs.developers.optimizely.com/feature-experimentation/docs/advanced-audience-targeting-segment-qualification-methods-flutter) + +* [Send Optimizely Data Platform data using Advanced Audience Targeting](https://docs.developers.optimizely.com/feature-experimentation/docs/send-odp-data-using-advanced-audience-targeting-flutter) + + +### Bug Fixes + +* Crash fixed, fetchQualifiedSegments without options ([#64](https://github.com/optimizely/optimizely-flutter-sdk/pull/64)). +* Fix proguard for logback and dart version ([#68](https://github.com/optimizely/optimizely-flutter-sdk/pull/68)). + +### Functionality Enhancements + +* Add specific client name support to track event ([#72](https://github.com/optimizely/optimizely-flutter-sdk/pull/72)). +* Update Github Issue Templates ([#65](https://github.com/optimizely/optimizely-flutter-sdk/pull/65)). +* Add configurable log level support ([#63](https://github.com/optimizely/optimizely-flutter-sdk/pull/63)). + ## 2.0.0-beta September 21, 2023 diff --git a/README.md b/README.md index e8a6edf..2de1dd5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^1.0.1 + optimizely_flutter_sdk: ^2.0.0 ``` Then run diff --git a/lib/package_info.dart b/lib/package_info.dart index 4c8df19..adef0b3 100644 --- a/lib/package_info.dart +++ b/lib/package_info.dart @@ -3,5 +3,5 @@ class PackageInfo { static const String name = 'optimizely_flutter_sdk'; - static const String version = '2.0.0-beta'; -} \ No newline at end of file + static const String version = '2.0.0'; +} diff --git a/pubspec.yaml b/pubspec.yaml index bda345b..7ffd848 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 2.0.0-beta +version: 2.0.0 homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: diff --git a/test/optimizely_flutter_sdk_test.dart b/test/optimizely_flutter_sdk_test.dart index dd6bd7a..821e234 100644 --- a/test/optimizely_flutter_sdk_test.dart +++ b/test/optimizely_flutter_sdk_test.dart @@ -1589,14 +1589,14 @@ void main() { TestUtils.sendTestTrackClientNameAndVersion( callHandler, 0, testSDKKey, "flutter/swift-sdk", "2.0.0"); TestUtils.sendTestTrackClientNameAndVersion( - callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0-beta"); + callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0"); expect(responses.length == 2, true); expect(responses[0]!.eventTags!["client_name"], "flutter/swift-sdk"); expect(responses[0]!.eventTags!["client_version"], "2.0.0"); expect(responses[1]!.eventTags!["client_name"], "flutter/android-sdk"); - expect(responses[1]!.eventTags!["client_version"], "2.0.0-beta"); + expect(responses[1]!.eventTags!["client_version"], "2.0.0"); }); @@ -1611,7 +1611,7 @@ void main() { var callHandler = OptimizelyClientWrapper.methodCallHandler; tester?.setMockMethodCallHandler(channel, callHandler); TestUtils.sendTestClientNameAndVersionLogEventNotification( - callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0-beta"); + callHandler, 0, testSDKKey, "flutter/android-sdk", "2.0.0"); TestUtils.sendTestClientNameAndVersionLogEventNotification( callHandler, 0, testSDKKey, "flutter/swift-sdk", "2.0.0"); @@ -1619,7 +1619,7 @@ void main() { expect(responses.length == 2, true); expect(responses[0]!.params!["client_name"], "flutter/android-sdk"); - expect(responses[0]!.params!["client_version"], "2.0.0-beta"); + expect(responses[0]!.params!["client_version"], "2.0.0"); expect(responses[1]!.params!["client_name"], "flutter/swift-sdk"); expect(responses[1]!.params!["client_version"], "2.0.0"); }); From 25ee944d06b624e495de5987613109144d606c15 Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:06:06 +0600 Subject: [PATCH 06/12] [FSSDK-10374] chore: migration of flutter's gradle plugins (#74) --- android/build.gradle | 29 ++++++++---------------- example/android/app/build.gradle | 20 ++++++++-------- example/android/build.gradle | 14 ++---------- example/android/settings.gradle | 39 +++++++++++++++++++++++++------- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 9934507..cdec407 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,24 +1,17 @@ +plugins { + id "com.android.library" +} + group 'com.optimizely.optimizely_flutter_sdk' version '1.0' -buildscript { - - def version_name = System.getenv('TRAVIS_TAG') - if (version_name != null) { - rootProject.ext.version_name = version_name - } else { - rootProject.ext.version_name = 'debugVersion' - } - - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' - } +def version_name = System.getenv('TRAVIS_TAG') +if (version_name != null) { + rootProject.ext.version_name = version_name +} else { + rootProject.ext.version_name = 'debugVersion' } + configurations { all*.exclude group: 'com.google.guava', module: 'listenablefuture' } @@ -29,7 +22,6 @@ rootProject.allprojects { } } -apply plugin: 'com.android.library' ext { compile_sdk_version = 32 @@ -71,7 +63,6 @@ android { } - dependencies { implementation 'androidx.multidex:multidex:2.0.0' implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 89fc349..415ec79 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,3 +1,10 @@ + +plugins { + id "com.android.application" + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,11 +13,6 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -21,10 +23,6 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { compileSdkVersion 32 ndkVersion flutter.ndkVersion @@ -57,3 +55,7 @@ android { flutter { source '../..' } + +dependencies { + implementation 'com.android.support:multidex:1.0.3' +} diff --git a/example/android/build.gradle b/example/android/build.gradle index 58051f6..81717b6 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,18 +1,8 @@ -buildscript { - ext.kotlin_version = '1.6.10' - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} ext { android_sdk_version = "4.0.0" } + allprojects { repositories { google() @@ -28,6 +18,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 44e62bc..5710b01 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,11 +1,34 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + + settings.ext.flutterSdkPath = flutterSdkPath() + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + repositories { + google() + mavenCentral() + gradlePluginPortal() + } + resolutionStrategy { + eachPlugin { + if (requested.id.namespace == 'dev.flutter') { + useModule("dev.flutter:${requested.id.name}:${requested.version}") + } + } + } +} -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.2.1" apply false + id "org.jetbrains.kotlin.android" version "1.6.10" apply false +} + +include ":app" -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" From 48d4dd5c8ff6d42ad2990c1661f348bb46d99d8e Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Fri, 26 Jul 2024 23:55:55 +0600 Subject: [PATCH 07/12] chore: update version and fix warning (#76) --- CHANGELOG.md | 7 +++++++ README.md | 2 +- lib/package_info.dart | 2 +- lib/src/data_objects/decide_response.dart | 1 + lib/src/data_objects/optimizely_config.dart | 4 ++++ lib/src/optimizely_client_wrapper.dart | 2 +- pubspec.yaml | 2 +- 7 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e77038..6cf3ba9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Optimizely Flutter SDK Changelog +## 2.0.1 +July 25, 2024 + +### Bug Fixes + +* Migration of flutter's gradle plugins ([#74](https://github.com/optimizely/optimizely-flutter-sdk/pull/74)). + ## 2.0.0 January 23, 2024 diff --git a/README.md b/README.md index 2de1dd5..9fbc097 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^2.0.0 + optimizely_flutter_sdk: ^2.0.1 ``` Then run diff --git a/lib/package_info.dart b/lib/package_info.dart index adef0b3..2ccb4b5 100644 --- a/lib/package_info.dart +++ b/lib/package_info.dart @@ -3,5 +3,5 @@ class PackageInfo { static const String name = 'optimizely_flutter_sdk'; - static const String version = '2.0.0'; + static const String version = '2.0.1'; } diff --git a/lib/src/data_objects/decide_response.dart b/lib/src/data_objects/decide_response.dart index dc2809a..29f8cdf 100644 --- a/lib/src/data_objects/decide_response.dart +++ b/lib/src/data_objects/decide_response.dart @@ -77,6 +77,7 @@ class BaseDecideResponse extends BaseResponse { if (json[Constants.responseResult] is Map) { final decisionsMap = Map.from(json[Constants.responseResult]); + // ignore: unnecessary_set_literal decisionsMap.forEach((k, v) => { if (v is Map) {_decisions[k] = Decision(Map.from(v))} diff --git a/lib/src/data_objects/optimizely_config.dart b/lib/src/data_objects/optimizely_config.dart index 51afbef..b771cc0 100644 --- a/lib/src/data_objects/optimizely_config.dart +++ b/lib/src/data_objects/optimizely_config.dart @@ -33,6 +33,7 @@ class OptimizelyConfig { if (optimizelyConfig[Constants.experimentsMap] is Map) { final experimentsMapDynamic = Map.from(optimizelyConfig[Constants.experimentsMap]); + // ignore: unnecessary_set_literal experimentsMapDynamic.forEach((k, v) => { if (v is Map) { @@ -45,6 +46,7 @@ class OptimizelyConfig { if (optimizelyConfig[Constants.featuresMap] is Map) { final featuresMapDynamic = Map.from(optimizelyConfig[Constants.featuresMap]); + // ignore: unnecessary_set_literal featuresMapDynamic.forEach((k, v) => { if (v is Map) { @@ -288,6 +290,7 @@ class OptimizelyExperiment { if (parsedJson[Constants.variationsMap] is Map) { final variationsMapDynamic = Map.from(parsedJson[Constants.variationsMap]); + // ignore: unnecessary_set_literal variationsMapDynamic.forEach((k, v) => { if (v is Map) { @@ -338,6 +341,7 @@ class OptimizelyVariation { if (parsedJson[Constants.variablesMap] is Map) { final variablesMapDynamic = Map.from(parsedJson[Constants.variablesMap]); + // ignore: unnecessary_set_literal variablesMapDynamic.forEach((k, v) => { if (v is Map) { diff --git a/lib/src/optimizely_client_wrapper.dart b/lib/src/optimizely_client_wrapper.dart index 590d17c..4d6e0c0 100644 --- a/lib/src/optimizely_client_wrapper.dart +++ b/lib/src/optimizely_client_wrapper.dart @@ -67,7 +67,7 @@ class OptimizelyClientWrapper { _channel.setMethodCallHandler(methodCallHandler); final convertedOptions = Utils.convertDecideOptions(defaultDecideOptions); final convertedLogLevel = Utils.convertLogLevel(defaultLogLevel); - final sdkVersion = PackageInfo.version; + const sdkVersion = PackageInfo.version; Map requestDict = { Constants.sdkKey: sdkKey, diff --git a/pubspec.yaml b/pubspec.yaml index 7ffd848..53e822c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 2.0.0 +version: 2.0.1 homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: From 8598e932bde5a318798f704e3264217bae8fae1f Mon Sep 17 00:00:00 2001 From: Farhan Anjum Date: Fri, 27 Sep 2024 22:25:57 +0600 Subject: [PATCH 08/12] [FSSDK-10665] fix: Github Actions YAML files vulnerable to script injections corrected (#77) --- .github/workflows/flutter.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index ed8d977..89d9093 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -37,14 +37,18 @@ jobs: path: 'home/runner/travisci-tools' ref: 'master' - name: set SDK Branch if PR + env: + HEAD_REF: ${{ github.head_ref }} if: ${{ github.event_name == 'pull_request' }} run: | - echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV + echo "SDK_BRANCH=$HEAD_REF" >> $GITHUB_ENV - name: set SDK Branch if not pull request + env: + REF_NAME: ${{ github.ref_name }} if: ${{ github.event_name != 'pull_request' }} run: | - echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV + echo "SDK_BRANCH=$REF_NAME" >> $GITHUB_ENV + echo "TRAVIS_BRANCH=$REF_NAME" >> $GITHUB_ENV - name: Trigger build env: SDK: android @@ -75,14 +79,18 @@ jobs: path: 'home/runner/travisci-tools' ref: 'master' - name: set SDK Branch if PR + env: + HEAD_REF: ${{ github.head_ref }} if: ${{ github.event_name == 'pull_request' }} run: | - echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV + echo "SDK_BRANCH=$HEAD_REF" >> $GITHUB_ENV - name: set SDK Branch if not pull request + env: + REF_NAME: ${{ github.ref_name }} if: ${{ github.event_name != 'pull_request' }} run: | - echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV + echo "SDK_BRANCH=$REF_NAME" >> $GITHUB_ENV + echo "TRAVIS_BRANCH=$REF_NAME" >> $GITHUB_ENV - name: Trigger build env: SDK: ios From dc4afe8d5108aa813cf8742614e33bed72453165 Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Thu, 28 Nov 2024 20:29:12 +0600 Subject: [PATCH 09/12] [FSSDK-10759] feat: make vuid optln (#78) VUID optln implemented for flutter --- .github/workflows/flutter.yml | 25 ++++++++++ android/build.gradle | 2 +- .../OptimizelyFlutterClient.java | 10 +++- .../helper_classes/Constants.java | 1 + ios/Classes/HelperClasses/Constants.swift | 1 + .../SwiftOptimizelyFlutterSdkPlugin.swift | 10 ++-- ios/optimizely_flutter_sdk.podspec | 2 +- lib/src/data_objects/get_vuid_response.dart | 2 +- lib/src/data_objects/sdk_settings.dart | 3 ++ lib/src/optimizely_client_wrapper.dart | 1 + lib/src/utils/constants.dart | 1 + test/optimizely_flutter_sdk_test.dart | 48 +++++++++++++++---- 12 files changed, 91 insertions(+), 15 deletions(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 89d9093..fe24b49 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -5,6 +5,16 @@ on: branches: [ "master" ] pull_request: branches: [ "master" ] + # workflow_dispatch: + # inputs: + # sdk_branch: + # description: "Specify the SDK branch" + # required: false + # default: "master" + # testapp_branch: + # description: "Specify the test app branch" + # required: false + # default: "master" jobs: unit_test_coverage: @@ -36,6 +46,21 @@ jobs: repository: 'optimizely/travisci-tools' path: 'home/runner/travisci-tools' ref: 'master' + # Set SDK Branch based on input or PR/Push + # - name: Set SDK Branch and Test App Branch + # run: | + # # If manually triggered + # if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + # echo "SDK_BRANCH=${{ github.event.inputs.sdk_branch || 'master' }}" >> $GITHUB_ENV + # echo "TESTAPP_BRANCH=${{ github.event.inputs.testapp_branch || 'master' }}" >> $GITHUB_ENV + # # If triggered by PR + # elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + # echo "SDK_BRANCH=${{ github.head_ref }}" >> $GITHUB_ENV + # # If triggered by push + # else + # echo "SDK_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV + # echo "TRAVIS_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV + # fi - name: set SDK Branch if PR env: HEAD_REF: ${{ github.head_ref }} diff --git a/android/build.gradle b/android/build.gradle index cdec407..12f972d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -74,7 +74,7 @@ dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:4.0.0" + implementation "com.optimizely.ab:android-sdk:5.0.0" implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java index c571c2f..cf85e3d 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java @@ -55,6 +55,7 @@ import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.DISABLE_ODP; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.ENABLE_VUID; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_SIZE; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_TIMEOUT_IN_SECONDS; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.TIMEOUT_FOR_ODP_EVENT_IN_SECONDS; @@ -144,6 +145,7 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N int timeoutForSegmentFetchInSecs = 10; int timeoutForOdpEventInSecs = 10; boolean disableOdp = false; + boolean enableVuid = false; Map sdkSettings = argumentsParser.getOptimizelySdkSettings(); if (sdkSettings != null) { if (sdkSettings.containsKey(SEGMENTS_CACHE_SIZE)) { @@ -161,6 +163,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N if (sdkSettings.containsKey(DISABLE_ODP)) { disableOdp = (boolean) sdkSettings.get(DISABLE_ODP); } + if (sdkSettings.containsKey(ENABLE_VUID)) { + enableVuid = (boolean) sdkSettings.get(ENABLE_VUID); + } } // Creating new instance OptimizelyManager.Builder optimizelyManagerBuilder = OptimizelyManager.builder() @@ -179,6 +184,9 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N if (disableOdp) { optimizelyManagerBuilder.withODPDisabled(); } + if (enableVuid) { + optimizelyManagerBuilder.withVuidEnabled(); + } OptimizelyManager optimizelyManager = optimizelyManagerBuilder.build(context); optimizelyManager.initialize(context, null, (OptimizelyClient client) -> { @@ -471,7 +479,7 @@ protected void getVuid(ArgumentsParser argumentsParser, @NonNull Result result) if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) { return; } - result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), "")); + result.success(createResponse(optimizelyClient.getVuid() != null, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), "")); } /// Checks if the user is qualified for the given segment. diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java index 0c73d32..62f0ce9 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java @@ -96,6 +96,7 @@ public static class RequestParameterKey { public static final String TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS = "timeoutForSegmentFetchInSecs"; public static final String TIMEOUT_FOR_ODP_EVENT_IN_SECONDS = "timeoutForOdpEventInSecs"; public static final String DISABLE_ODP = "disableOdp"; + public static final String ENABLE_VUID = "enableVuid"; } public static class ErrorMessage { diff --git a/ios/Classes/HelperClasses/Constants.swift b/ios/Classes/HelperClasses/Constants.swift index f3ca6d5..a29370a 100644 --- a/ios/Classes/HelperClasses/Constants.swift +++ b/ios/Classes/HelperClasses/Constants.swift @@ -114,6 +114,7 @@ struct RequestParameterKey { static let timeoutForSegmentFetchInSecs = "timeoutForSegmentFetchInSecs" static let timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs" static let disableOdp = "disableOdp" + static let enableVuid = "enableVuid" static let sdkVersion = "sdkVersion"; } diff --git a/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift b/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift index 8a2fd75..7c093c4 100644 --- a/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift +++ b/ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift @@ -118,6 +118,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { var timeoutForSegmentFetchInSecs: Int = 10 var timeoutForOdpEventInSecs: Int = 10 var disableOdp: Bool = false + var enableVuid: Bool = false var sdkVersion = parameters[RequestParameterKey.sdkVersion] as? String var sdkName = Utils.sdkName @@ -137,8 +138,11 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { if let isOdpDisabled = sdkSettings[RequestParameterKey.disableOdp] as? Bool { disableOdp = isOdpDisabled } + if let isEnableVuid = sdkSettings[RequestParameterKey.enableVuid] as? Bool { + enableVuid = isEnableVuid + } } - let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, sdkName: sdkName, sdkVersion: sdkVersion) + let optimizelySdkSettings = OptimizelySdkSettings(segmentsCacheSize: segmentsCacheSize, segmentsCacheTimeoutInSecs: segmentsCacheTimeoutInSecs, timeoutForSegmentFetchInSecs: timeoutForSegmentFetchInSecs, timeoutForOdpEventInSecs: timeoutForOdpEventInSecs, disableOdp: disableOdp, enableVuid: enableVuid, sdkName: sdkName, sdkVersion: sdkVersion) // Datafile Download Interval var datafilePeriodicDownloadInterval = 10 * 60 // seconds @@ -374,7 +378,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { } else { userContextsTracker[sdkKey] = [userContextId: userContext] } - result(self.createResponse(success: true, result: [RequestParameterKey.userContextId: userContextId])) + result(self.createResponse(success: userContext != nil, result: [RequestParameterKey.userContextId: userContextId])) } /// Returns userId for the user context. @@ -442,7 +446,7 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin { guard let optimizelyClient = getOptimizelyClient(sdkKey: sdkKey, result: result) else { return } - result(self.createResponse(success: true, result: [RequestParameterKey.vuid: optimizelyClient.vuid])) + result(self.createResponse(success: optimizelyClient.vuid != nil, result: [RequestParameterKey.vuid: optimizelyClient.vuid])) } /// Checks if the user is qualified for the given segment. diff --git a/ios/optimizely_flutter_sdk.podspec b/ios/optimizely_flutter_sdk.podspec index 4da4408..14f4dbc 100644 --- a/ios/optimizely_flutter_sdk.podspec +++ b/ios/optimizely_flutter_sdk.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'OptimizelySwiftSDK', '4.0.0' + s.dependency 'OptimizelySwiftSDK', '5.0.0' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/lib/src/data_objects/get_vuid_response.dart b/lib/src/data_objects/get_vuid_response.dart index 4be045b..e5fcfb0 100644 --- a/lib/src/data_objects/get_vuid_response.dart +++ b/lib/src/data_objects/get_vuid_response.dart @@ -18,7 +18,7 @@ import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart'; import 'package:optimizely_flutter_sdk/src/utils/constants.dart'; class GetVuidResponse extends BaseResponse { - String vuid = ""; + String? vuid; GetVuidResponse(Map json) : super(json) { if (json[Constants.responseResult] is Map) { diff --git a/lib/src/data_objects/sdk_settings.dart b/lib/src/data_objects/sdk_settings.dart index 412432a..448a2e8 100644 --- a/lib/src/data_objects/sdk_settings.dart +++ b/lib/src/data_objects/sdk_settings.dart @@ -25,6 +25,8 @@ class SDKSettings { final int timeoutForOdpEventInSecs; // Set this flag to true (default = false) to disable ODP features final bool disableOdp; + // Set this flag to true (default = false) to enable VUID feature + final bool enableVuid; const SDKSettings({ this.segmentsCacheSize = 100, // Default segmentsCacheSize @@ -33,5 +35,6 @@ class SDKSettings { 10, // Default timeoutForSegmentFetchInSecs this.timeoutForOdpEventInSecs = 10, // Default timeoutForOdpEventInSecs this.disableOdp = false, // Default disableOdp + this.enableVuid = false, // Default disableVuid }); } diff --git a/lib/src/optimizely_client_wrapper.dart b/lib/src/optimizely_client_wrapper.dart index 4d6e0c0..fb4fce0 100644 --- a/lib/src/optimizely_client_wrapper.dart +++ b/lib/src/optimizely_client_wrapper.dart @@ -90,6 +90,7 @@ class OptimizelyClientWrapper { sdkSettings.timeoutForSegmentFetchInSecs, Constants.timeoutForOdpEventInSecs: sdkSettings.timeoutForOdpEventInSecs, Constants.disableOdp: sdkSettings.disableOdp, + Constants.enableVuid: sdkSettings.enableVuid, }; requestDict[Constants.optimizelySdkSettings] = optimizelySdkSettings; diff --git a/lib/src/utils/constants.dart b/lib/src/utils/constants.dart index 7ef9547..fb33033 100644 --- a/lib/src/utils/constants.dart +++ b/lib/src/utils/constants.dart @@ -131,6 +131,7 @@ class Constants { "timeoutForSegmentFetchInSecs"; static const String timeoutForOdpEventInSecs = "timeoutForOdpEventInSecs"; static const String disableOdp = "disableOdp"; + static const String enableVuid = "enableVuid"; // Response keys static const String responseSuccess = "success"; diff --git a/test/optimizely_flutter_sdk_test.dart b/test/optimizely_flutter_sdk_test.dart index 821e234..862c4b0 100644 --- a/test/optimizely_flutter_sdk_test.dart +++ b/test/optimizely_flutter_sdk_test.dart @@ -56,7 +56,6 @@ void main() { SDKSettings sdkSettings = const SDKSettings(); int datafilePeriodicDownloadInterval = 0; String defaultLogLevel = "error"; - const MethodChannel channel = MethodChannel("optimizely_flutter_sdk"); dynamic mockOptimizelyConfig; @@ -106,6 +105,7 @@ void main() { timeoutForOdpEventInSecs: settings[Constants.timeoutForOdpEventInSecs], disableOdp: settings[Constants.disableOdp], + enableVuid: settings[Constants.enableVuid], ); } @@ -175,9 +175,19 @@ void main() { }; case Constants.createUserContextMethod: expect(methodCall.arguments[Constants.sdkKey], isNotEmpty); - if (methodCall.arguments[Constants.userId] != null) { + var resultUserId = userContextId; + if (methodCall.arguments[Constants.userId] == null) { + if (sdkSettings.enableVuid) { + resultUserId = vuid; + } else { + return { + Constants.responseSuccess: false, + }; + } + } else if (methodCall.arguments[Constants.userId] != null) { expect(methodCall.arguments[Constants.userId], equals(userId)); } + if (methodCall.arguments[Constants.attributes]["abc"] != null) { expect(methodCall.arguments[Constants.attributes]["abc"], equals(attributes["abc"])); @@ -185,7 +195,7 @@ void main() { expect(methodCall.arguments[Constants.userContextId], isNull); return { Constants.responseSuccess: true, - Constants.responseResult: {Constants.userContextId: userContextId}, + Constants.responseResult: {Constants.userContextId: resultUserId}, }; case Constants.getUserIdMethod: expect(methodCall.arguments[Constants.sdkKey], isNotEmpty); @@ -266,6 +276,8 @@ void main() { case Constants.getVuidMethod: expect(methodCall.arguments[Constants.sdkKey], isNotEmpty); expect(methodCall.arguments[Constants.userContextId], isNull); + expect(methodCall.arguments[Constants.vuid], isNull); + var vuid = sdkSettings.enableVuid ? "vuid_123" : null; return { Constants.responseSuccess: true, Constants.responseResult: {Constants.vuid: vuid}, @@ -376,6 +388,7 @@ void main() { tearDown(() { tester?.setMockMethodCallHandler(channel, null); + sdkSettings = const SDKSettings(); }); group("Integration: OptimizelyFlutterSdk MethodChannel", () { @@ -650,8 +663,17 @@ void main() { expect(userContext, isNotNull); }); - test("should succeed null userId", () async { + test("should fail when disable vuid and userId null", () async { var sdk = OptimizelyFlutterSdk(testSDKKey); + sdk.initializeClient(); + var userContext = await sdk.createUserContext(attributes: attributes); + expect(userContext, isNull); + }); + + test("should succed when enable vuid and userId null", () async { + const settings = SDKSettings(enableVuid: true); + var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings); + sdk.initializeClient(); var userContext = await sdk.createUserContext(attributes: attributes); expect(userContext, isNotNull); }); @@ -662,10 +684,11 @@ void main() { expect(userContext, isNotNull); }); - test("should succeed null userId and attributes", () async { + test("should not succeed null userId and attributes", () async { var sdk = OptimizelyFlutterSdk(testSDKKey); + sdk.initializeClient(); var userContext = await sdk.createUserContext(); - expect(userContext, isNotNull); + expect(userContext, isNull); }); }); @@ -769,11 +792,20 @@ void main() { }); group("getVuid()", () { - test("should succeed", () async { + test("by default should return null vuid", () async { var sdk = OptimizelyFlutterSdk(testSDKKey); + sdk.initializeClient(); + var response = await sdk.getVuid(); + expect(response.success, isTrue); + expect(response.vuid, isNull); + }); + test("should return vuid when enableVuid true", () async { + const settings = SDKSettings(enableVuid: true); + var sdk = OptimizelyFlutterSdk(testSDKKey, sdkSettings: settings); + sdk.initializeClient(); var response = await sdk.getVuid(); expect(response.success, isTrue); - expect(response.vuid, equals(vuid)); + expect(response.vuid, "vuid_123"); }); }); From 48c1b5c58acadcb353c9ac489276f7f0140da37c Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:55:30 +0600 Subject: [PATCH 10/12] chore: version updated (#79) --- CHANGELOG.md | 11 +++++++++++ README.md | 2 +- lib/package_info.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cf3ba9..8c2f2b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Optimizely Flutter SDK Changelog +## 3.0.0 +November 28th, 2024 + +### Breaking Changes +* VUID configuration is now independent of ODP ([#78](https://github.com/optimizely/optimizely-flutter-sdk/pull/78)) +* When VUID is disabled: + * `vuid` is not generated or saved. + * `client-initialized` event will not auto fired on SDK init. + * `vuid` is not included in the odp events as a default attribute. + * `createUserContext()` will be rejected if `userId` is not provided. + ## 2.0.1 July 25, 2024 diff --git a/README.md b/README.md index 9fbc097..c851ae5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^2.0.1 + optimizely_flutter_sdk: ^3.0.0 ``` Then run diff --git a/lib/package_info.dart b/lib/package_info.dart index 2ccb4b5..cbf0165 100644 --- a/lib/package_info.dart +++ b/lib/package_info.dart @@ -3,5 +3,5 @@ class PackageInfo { static const String name = 'optimizely_flutter_sdk'; - static const String version = '2.0.1'; + static const String version = '3.0.0'; } diff --git a/pubspec.yaml b/pubspec.yaml index 53e822c..fb899c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 2.0.1 +version: 3.0.0 homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: From 4b3c53c27a3dc9bad19e6d33a13a37f705b56bbe Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Wed, 4 Jun 2025 00:16:29 +0600 Subject: [PATCH 11/12] [FSSDK-11465] chore: add netspring support (#80) --- android/build.gradle | 2 +- ios/optimizely_flutter_sdk.podspec | 2 +- lib/src/optimizely_client_wrapper.dart | 4 ---- lib/src/utils/constants.dart | 2 ++ test/test_utils.dart | 31 +++++++++++++++++++++++--- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 12f972d..5d4e3ff 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -74,7 +74,7 @@ dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:5.0.0" + implementation "com.optimizely.ab:android-sdk:5.0.1" implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/ios/optimizely_flutter_sdk.podspec b/ios/optimizely_flutter_sdk.podspec index 14f4dbc..2aa6953 100644 --- a/ios/optimizely_flutter_sdk.podspec +++ b/ios/optimizely_flutter_sdk.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'OptimizelySwiftSDK', '5.0.0' + s.dependency 'OptimizelySwiftSDK', '5.1.1' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } diff --git a/lib/src/optimizely_client_wrapper.dart b/lib/src/optimizely_client_wrapper.dart index fb4fce0..a0869b9 100644 --- a/lib/src/optimizely_client_wrapper.dart +++ b/lib/src/optimizely_client_wrapper.dart @@ -371,7 +371,6 @@ class OptimizelyClientWrapper { if (checkCallBackExist(sdkKey, callback)) { // ignore: avoid_print - print("callback already exists."); return -1; } @@ -417,7 +416,6 @@ class OptimizelyClientWrapper { if (checkCallBackExist(sdkKey, callback)) { // ignore: avoid_print - print("callback already exists."); return -1; } @@ -440,7 +438,6 @@ class OptimizelyClientWrapper { if (checkCallBackExist(sdkKey, callback)) { // ignore: avoid_print - print("callback already exists."); return -1; } @@ -464,7 +461,6 @@ class OptimizelyClientWrapper { if (checkCallBackExist(sdkKey, callback)) { // ignore: avoid_print - print("callback already exists."); return -1; } diff --git a/lib/src/utils/constants.dart b/lib/src/utils/constants.dart index fb33033..2bb5421 100644 --- a/lib/src/utils/constants.dart +++ b/lib/src/utils/constants.dart @@ -62,7 +62,9 @@ class Constants { static const String userContextId = "userContextId"; static const String userContext = "userContext"; static const String experiment = "experiment"; + static const String experimentId = "experimentId"; static const String variation = "variation"; + static const String variationId = "variationId"; static const String userId = "userId"; static const String vuid = "vuid"; static const String experimentKey = "experimentKey"; diff --git a/test/test_utils.dart b/test/test_utils.dart index 986bd8e..350c35e 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -89,7 +89,14 @@ class TestUtils { handler(MethodCall(Constants.decisionCallBackListener, { Constants.id: id, Constants.sdkKey: sdkKey, - Constants.payload: {Constants.type: "$id", Constants.userId: "test"} + Constants.payload: { + Constants.type: "$id", + Constants.userId: "test", + Constants.decisionInfo: const { + Constants.experimentId: "experiment_12345", + Constants.variationId: "variation_12345", + }, + } })); } @@ -129,7 +136,15 @@ class TestUtils { Constants.eventKey: "$id", Constants.userId: "test", Constants.attributes: {"test": id}, - Constants.eventTags: {"testTag": id} + Constants.eventTags: { + "testTag": id, + "nestedTag": { + "string_key": "stringValue", + "int_key": 123, + "double_key": 123.456, + "bool_key": true + } + } }; handler(MethodCall(Constants.trackCallBackListener, { Constants.id: id, @@ -145,6 +160,12 @@ class TestUtils { Constants.attributes: {"test": id}, Constants.eventTags: { "testTag": id, + "nestedTag": { + "string_key": "stringValue", + "int_key": 123, + "double_key": 123.456, + "bool_key": true + }, "client_name": clientName, "client_version": sdkVersion } @@ -179,7 +200,11 @@ class TestUtils { static bool testDecisionNotificationPayload( List notifications, int id, int actualID) { if (notifications[id].type != "$actualID" || - notifications[id].userId != "test") { + notifications[id].userId != "test" || + notifications[id].decisionInfo[Constants.experimentId] != + "experiment_12345" || + notifications[id].decisionInfo[Constants.variationId] != + "variation_12345") { return false; } return true; From bbb47903d00babd488b20af9f806b926d215c967 Mon Sep 17 00:00:00 2001 From: Muzahidul Islam <129880873+muzahidul-opti@users.noreply.github.com> Date: Fri, 13 Jun 2025 00:45:15 +0600 Subject: [PATCH 12/12] [FSSDK-11453] chore: prepare for release 3.0.1 (#81) * Update doc for release 3.0.1 * update change log --- CHANGELOG.md | 7 +++++++ README.md | 2 +- lib/package_info.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c2f2b8..6e530c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Optimizely Flutter SDK Changelog +## 3.0.1 +Jun 4th, 2025 + +### Functionality Enhancements + +* Add experiment id and variation id added into decision notification payload ([#80](https://github.com/optimizely/optimizely-flutter-sdk/pull/80)) + ## 3.0.0 November 28th, 2024 diff --git a/README.md b/README.md index c851ae5..1b125d5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Other Flutter platforms are not currently supported by this SDK. To add the flutter-sdk to your project dependencies, include the following in your app's pubspec.yaml: ``` - optimizely_flutter_sdk: ^3.0.0 + optimizely_flutter_sdk: ^3.0.1 ``` Then run diff --git a/lib/package_info.dart b/lib/package_info.dart index cbf0165..0bdd780 100644 --- a/lib/package_info.dart +++ b/lib/package_info.dart @@ -3,5 +3,5 @@ class PackageInfo { static const String name = 'optimizely_flutter_sdk'; - static const String version = '3.0.0'; + static const String version = '3.0.1'; } diff --git a/pubspec.yaml b/pubspec.yaml index fb899c2..188939d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: optimizely_flutter_sdk description: This repository houses the Flutter SDK for use with Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts. -version: 3.0.0 +version: 3.0.1 homepage: https://github.com/optimizely/optimizely-flutter-sdk environment: