diff --git a/CHANGELOG.md b/CHANGELOG.md index fa66315..f9400b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 7.2.0 +* Added attach/detach remote configuration functions + ## 7.1.0 * Added remote configuration source property. * Added rate limits for API calls. diff --git a/android/build.gradle b/android/build.gradle index 71cef92..7734954 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -43,6 +43,6 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation "io.qonversion.sandwich:sandwich:3.1.1" + implementation "io.qonversion.sandwich:sandwich:3.2.0" implementation 'com.google.code.gson:gson:2.9.0' } diff --git a/android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionPlugin.kt b/android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionPlugin.kt index 30931e3..696ef98 100644 --- a/android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionPlugin.kt +++ b/android/src/main/kotlin/com/qonversion/flutter/sdk/qonversion_flutter_sdk/QonversionPlugin.kt @@ -138,6 +138,8 @@ class QonversionPlugin : MethodCallHandler, FlutterPlugin, ActivityAware { "checkTrialIntroEligibility" -> checkTrialIntroEligibility(args, result) "attachUserToExperiment" -> attachUserToExperiment(args, result) "detachUserFromExperiment" -> detachUserFromExperiment(args, result) + "attachUserToRemoteConfiguration" -> attachUserToRemoteConfiguration(args, result) + "detachUserFromRemoteConfiguration" -> detachUserFromRemoteConfiguration(args, result) "storeSdkInfo" -> storeSdkInfo(args, result) "identify" -> identify(args["userId"] as? String, result) "automationsSetNotificationsToken" -> automationsPlugin.setNotificationsToken(args["notificationsToken"] as? String, result) @@ -280,7 +282,6 @@ class QonversionPlugin : MethodCallHandler, FlutterPlugin, ActivityAware { } private fun attachUserToExperiment(args: Map, result: Result) { - @Suppress("UNCHECKED_CAST") val experimentId = args["experimentId"] as? String ?: return result.noNecessaryDataError() val groupId = args["groupId"] as? String ?: return result.noNecessaryDataError() @@ -288,12 +289,23 @@ class QonversionPlugin : MethodCallHandler, FlutterPlugin, ActivityAware { } private fun detachUserFromExperiment(args: Map, result: Result) { - @Suppress("UNCHECKED_CAST") val experimentId = args["experimentId"] as? String ?: return result.noNecessaryDataError() qonversionSandwich.detachUserFromExperiment(experimentId, result.toJsonResultListener()) } + private fun attachUserToRemoteConfiguration(args: Map, result: Result) { + val remoteConfigurationId = args["remoteConfigurationId"] as? String ?: return result.noNecessaryDataError() + + qonversionSandwich.attachUserToRemoteConfiguration(remoteConfigurationId, result.toJsonResultListener()) + } + + private fun detachUserFromRemoteConfiguration(args: Map, result: Result) { + val remoteConfigurationId = args["remoteConfigurationId"] as? String ?: return result.noNecessaryDataError() + + qonversionSandwich.detachUserFromRemoteConfiguration(remoteConfigurationId, result.toJsonResultListener()) + } + private fun userInfo(result: Result) { qonversionSandwich.userInfo(result.toResultListener()) } diff --git a/ios/Classes/SwiftQonversionPlugin.swift b/ios/Classes/SwiftQonversionPlugin.swift index ab75795..a7a42d6 100644 --- a/ios/Classes/SwiftQonversionPlugin.swift +++ b/ios/Classes/SwiftQonversionPlugin.swift @@ -138,6 +138,12 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { case "detachUserFromExperiment": return detachUserFromExperiment(args, result) + case "attachUserToRemoteConfiguration": + return attachUserToRemoteConfiguration(args, result) + + case "detachUserFromRemoteConfiguration": + return detachUserFromRemoteConfiguration(args, result) + case "automationsSetNotificationsToken": automationsPlugin?.setNotificationsToken(args["notificationsToken"] as? String, result) return @@ -295,6 +301,22 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { qonversionSandwich?.detachUserFromExperiment(with: experimentId, completion: getJsonCompletion(result)) } + + private func attachUserToRemoteConfiguration(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let remoteConfigurationId = args["remoteConfigurationId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.attachUserToRemoteConfiguration(with: remoteConfigurationId, completion: getJsonCompletion(result)) + } + + private func detachUserFromRemoteConfiguration(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let remoteConfigurationId = args["remoteConfigurationId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.detachUserFromRemoteConfiguration(with: remoteConfigurationId, completion: getJsonCompletion(result)) + } private func storeSdkInfo(_ args: [String: Any], _ result: @escaping FlutterResult) { guard let version = args["version"] as? String, diff --git a/ios/qonversion_flutter.podspec b/ios/qonversion_flutter.podspec index 666711e..38e0d69 100644 --- a/ios/qonversion_flutter.podspec +++ b/ios/qonversion_flutter.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.dependency 'Flutter' s.platform = :ios, '9.0' - s.dependency "QonversionSandwich", "3.1.1" + s.dependency "QonversionSandwich", "3.2.0" # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } diff --git a/lib/src/internal/constants.dart b/lib/src/internal/constants.dart index 28704b6..7ad4fca 100644 --- a/lib/src/internal/constants.dart +++ b/lib/src/internal/constants.dart @@ -27,6 +27,7 @@ class Constants { static const kConfigData = 'configData'; static const kExperimentId = 'experimentId'; static const kGroupId = 'groupId'; + static const kRemoteConfigurationId = 'remoteConfigurationId'; // MethodChannel methods names static const mInitialize = 'initialize'; @@ -57,6 +58,8 @@ class Constants { static const mRemoteConfig = 'remoteConfig'; static const mAttachUserToExperiment = 'attachUserToExperiment'; static const mDetachUserFromExperiment = 'detachUserFromExperiment'; + static const mAttachUserToRemoteConfiguration = 'attachUserToRemoteConfiguration'; + static const mDetachUserFromRemoteConfiguration = 'detachUserFromRemoteConfiguration'; static const mCollectAppleSearchAdsAttribution = 'collectAppleSearchAdsAttribution'; static const mPresentCodeRedemptionSheet = 'presentCodeRedemptionSheet'; static const mSubscribeAutomations = 'automationsSubscribe'; diff --git a/lib/src/internal/qonversion_internal.dart b/lib/src/internal/qonversion_internal.dart index 4218c41..6a67d43 100644 --- a/lib/src/internal/qonversion_internal.dart +++ b/lib/src/internal/qonversion_internal.dart @@ -11,7 +11,7 @@ import 'package:qonversion_flutter/src/internal/utils/string.dart'; import 'constants.dart'; class QonversionInternal implements Qonversion { - static const String _sdkVersion = "7.1.0"; + static const String _sdkVersion = "7.2.0"; final MethodChannel _channel = MethodChannel('qonversion_plugin'); @@ -240,6 +240,22 @@ class QonversionInternal implements Qonversion { return; } + Future attachUserToRemoteConfiguration(String remoteConfigurationId) async { + final args = { + Constants.kRemoteConfigurationId: remoteConfigurationId, + }; + await _channel.invokeMethod(Constants.mAttachUserToRemoteConfiguration, args); + return; + } + + Future detachUserFromRemoteConfiguration(String remoteConfigurationId) async { + final args = { + Constants.kRemoteConfigurationId: remoteConfigurationId, + }; + await _channel.invokeMethod(Constants.mDetachUserFromRemoteConfiguration, args); + return; + } + @override Future attribution(Map data, QAttributionProvider provider) { final args = { diff --git a/lib/src/qonversion.dart b/lib/src/qonversion.dart index bb33b2c..b4da719 100644 --- a/lib/src/qonversion.dart +++ b/lib/src/qonversion.dart @@ -188,6 +188,14 @@ abstract class Qonversion { /// Use this function to detach the user from the experiment. Future detachUserFromExperiment(String experimentId); + /// This function should be used for the test purposes only. Do not forget to delete the usage of this function before the release. + /// Use this function to attach the user to the remote configuration. + Future attachUserToRemoteConfiguration(String remoteConfigurationId); + + /// This function should be used for the test purposes only. Do not forget to delete the usage of this function before the release. + /// Use this function to detach the user from the remote configuration. + Future detachUserFromRemoteConfiguration(String remoteConfigurationId); + /// iOS only. Returns `null` if called on Android. /// /// Starts a promo purchase process with App Store [productId]. diff --git a/macos/Classes/SwiftQonversionPlugin.swift b/macos/Classes/SwiftQonversionPlugin.swift index 5bc3f6c..ca8f0da 100644 --- a/macos/Classes/SwiftQonversionPlugin.swift +++ b/macos/Classes/SwiftQonversionPlugin.swift @@ -116,6 +116,12 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { case "detachUserFromExperiment": return detachUserFromExperiment(args, result) + case "attachUserToRemoteConfiguration": + return attachUserToRemoteConfiguration(args, result) + + case "detachUserFromRemoteConfiguration": + return detachUserFromRemoteConfiguration(args, result) + default: return result(FlutterMethodNotImplemented) } @@ -269,6 +275,22 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { qonversionSandwich?.detachUserFromExperiment(with: experimentId, completion: getJsonCompletion(result)) } + + private func attachUserToRemoteConfiguration(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let remoteConfigurationId = args["remoteConfigurationId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.attachUserToRemoteConfiguration(with: remoteConfigurationId, completion: getJsonCompletion(result)) + } + + private func detachUserFromRemoteConfiguration(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let remoteConfigurationId = args["remoteConfigurationId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.detachUserFromRemoteConfiguration(with: remoteConfigurationId, completion: getJsonCompletion(result)) + } private func getDefaultCompletion(_ result: @escaping FlutterResult) -> BridgeCompletion { return { data, error in diff --git a/macos/qonversion_flutter.podspec b/macos/qonversion_flutter.podspec index fd70f60..a142bf1 100644 --- a/macos/qonversion_flutter.podspec +++ b/macos/qonversion_flutter.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.dependency 'FlutterMacOS' s.platform = :osx, '10.12' - s.dependency "QonversionSandwich", "3.1.1" + s.dependency "QonversionSandwich", "3.2.0" s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' diff --git a/pubspec.yaml b/pubspec.yaml index c18daab..6c4a552 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: qonversion_flutter description: Flutter plugin to implement in-app subscriptions and purchases. Validate user receipts and manage cross-platform access to paid content on your app. Android & iOS. -version: 7.1.0 +version: 7.2.0 homepage: 'https://qonversion.io' repository: 'https://github.com/qonversion/flutter-sdk'