From 2c91a3d4f2d9b171f58b923e5cf5caedf59125b6 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Thu, 21 Nov 2024 17:45:30 +0300 Subject: [PATCH 1/9] Promotional offers supported. --- android/build.gradle | 2 +- ios/Classes/SwiftQonversionPlugin.swift | 29 +++- ios/qonversion_flutter.podspec | 2 +- lib/qonversion_flutter.dart | 6 + lib/src/dto/automations/action_result.g.dart | 57 +----- lib/src/dto/automations/event.g.dart | 41 +---- lib/src/dto/eligibility.g.dart | 45 +---- lib/src/dto/entitlement.g.dart | 76 +++----- lib/src/dto/experiment.g.dart | 12 +- lib/src/dto/experiment_group.g.dart | 39 +---- lib/src/dto/offerings.g.dart | 58 ++----- lib/src/dto/product.dart | 8 +- lib/src/dto/product.g.dart | 58 ++----- lib/src/dto/promotional_offer.dart | 23 +++ lib/src/dto/promotional_offer.g.dart | 19 ++ lib/src/dto/purchase_options.dart | 15 +- lib/src/dto/purchase_options_builder.dart | 13 +- lib/src/dto/qonversion_error.g.dart | 42 +---- lib/src/dto/remote_config.g.dart | 18 +- lib/src/dto/remote_config_list.g.dart | 13 +- .../dto/remote_configuration_source.g.dart | 47 ++--- lib/src/dto/screen_presentation_config.g.dart | 2 +- lib/src/dto/sk_product/discount.g.dart | 63 ------- .../dto/sk_product/sk_payment_discount.dart | 42 +++++ .../dto/sk_product/sk_payment_discount.g.dart | 25 +++ ...k_product_wrapper.dart => sk_product.dart} | 52 +++--- lib/src/dto/sk_product/sk_product.g.dart | 49 ++++++ ...discount.dart => sk_product_discount.dart} | 32 ++-- .../dto/sk_product/sk_product_discount.g.dart | 36 ++++ .../dto/sk_product/sk_product_wrapper.g.dart | 48 ------ .../dto/sk_product/subscription_period.dart | 16 +- .../dto/sk_product/subscription_period.g.dart | 45 +---- lib/src/dto/sku_details/sku_details.g.dart | 72 +++----- .../product_inapp_details.g.dart | 10 +- .../product_installment_plan_details.g.dart | 11 +- .../product_offer_details.g.dart | 34 ++-- .../dto/store_product/product_price.g.dart | 17 +- .../product_pricing_phase.g.dart | 58 ++----- .../product_store_details.g.dart | 76 +++----- lib/src/dto/subscription_period.g.dart | 43 +---- lib/src/dto/transaction.dart | 5 + lib/src/dto/transaction.g.dart | 59 ++----- lib/src/dto/user.g.dart | 10 +- lib/src/dto/user_properties.g.dart | 13 +- lib/src/dto/user_property.g.dart | 11 +- lib/src/internal/constants.dart | 3 + lib/src/internal/mapper.dart | 50 ++++-- lib/src/internal/qonversion_internal.dart | 27 +++ lib/src/qonversion.dart | 2 + macos/Classes/SwiftQonversionPlugin.swift | 33 +++- macos/qonversion_flutter.podspec | 2 +- pubspec.lock | 163 ++++++++++-------- pubspec.yaml | 4 +- 53 files changed, 763 insertions(+), 973 deletions(-) create mode 100644 lib/src/dto/promotional_offer.dart create mode 100644 lib/src/dto/promotional_offer.g.dart delete mode 100644 lib/src/dto/sk_product/discount.g.dart create mode 100644 lib/src/dto/sk_product/sk_payment_discount.dart create mode 100644 lib/src/dto/sk_product/sk_payment_discount.g.dart rename lib/src/dto/sk_product/{sk_product_wrapper.dart => sk_product.dart} (77%) create mode 100644 lib/src/dto/sk_product/sk_product.g.dart rename lib/src/dto/sk_product/{discount.dart => sk_product_discount.dart} (73%) create mode 100644 lib/src/dto/sk_product/sk_product_discount.g.dart delete mode 100644 lib/src/dto/sk_product/sk_product_wrapper.g.dart diff --git a/android/build.gradle b/android/build.gradle index 1b3cd340..f85d5dd3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -51,6 +51,6 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation "io.qonversion.sandwich:sandwich:5.1.7" + implementation "io.qonversion.sandwich:sandwich:5.2.0" implementation 'com.google.code.gson:gson:2.9.0' } diff --git a/ios/Classes/SwiftQonversionPlugin.swift b/ios/Classes/SwiftQonversionPlugin.swift index d3459de9..8b517664 100644 --- a/ios/Classes/SwiftQonversionPlugin.swift +++ b/ios/Classes/SwiftQonversionPlugin.swift @@ -107,9 +107,12 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { switch call.method { case "initialize": return initialize(args, result) + + case "getPromotionalOffer": + return getPromotionalOffer(args, result) case "purchase": - return purchase(args["productId"] as? String, quantity: args["quantity"] as? Int, contextKeys: args["contextKeys"] as? [String], result) + return purchase(args, result) case "promoPurchase": return promoPurchase(args["productId"] as? String, result) @@ -204,19 +207,31 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { qonversionSandwich?.identify(userId, getDefaultCompletion(result)) } + private func getPromotionalOffer(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let productId = args["productId"] as? String else { + return result(FlutterError.noNecessaryData) + } + guard let discountId = args["discountId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.getPromotionalOffer(productId, productDiscountId:discountId, completion:getJsonCompletion(result)) + } + private func products(_ result: @escaping FlutterResult) { qonversionSandwich?.products(getDefaultCompletion(result)) } - private func purchase(_ productId: String?, quantity: Int?, contextKeys: [String]?, _ result: @escaping FlutterResult) { - guard let productId = productId else { + private func purchase(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let productId = args["productId"] as? String else { return result(FlutterError.noNecessaryData) } - - let contextKeys = contextKeys ?? [] - let quantity = quantity ?? 1 + + let contextKeys = args["contextKeys"] as? [String] ?? [] + let quantity = args["quantity"] as? Int ?? 1 + let promoOfferData = args["promoOffer"] as? [String: Any] ?? [:] - qonversionSandwich?.purchase(productId, quantity:quantity, contextKeys:contextKeys, completion: getJsonCompletion(result)) + qonversionSandwich?.purchase(productId, quantity:quantity, contextKeys:contextKeys, promoOffer:promoOfferData, completion:getJsonCompletion(result)) } private func promoPurchase(_ productId: String?, _ result: @escaping FlutterResult) { diff --git a/ios/qonversion_flutter.podspec b/ios/qonversion_flutter.podspec index df9689ae..50e2f681 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", "5.1.7" + s.dependency "QonversionSandwich", "5.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/qonversion_flutter.dart b/lib/qonversion_flutter.dart index b37abf0c..13990d95 100644 --- a/lib/qonversion_flutter.dart +++ b/lib/qonversion_flutter.dart @@ -6,6 +6,7 @@ export 'src/dto/automations/event_type.dart'; export 'src/dto/attribution_provider.dart'; export 'src/dto/eligibility.dart'; export 'src/dto/entitlement.dart'; +export 'src/dto/entitlement_grant_type.dart'; export 'src/dto/entitlement_renew_state.dart'; export 'src/dto/entitlement_source.dart'; export 'src/dto/entitlements_cache_lifetime.dart'; @@ -14,6 +15,7 @@ export 'src/dto/launch_mode.dart'; export 'src/dto/offerings.dart'; export 'src/dto/product.dart'; export 'src/dto/product_type.dart'; +export 'src/dto/promotional_offer.dart'; export 'src/dto/purchase_model.dart'; export 'src/dto/purchase_options.dart'; export 'src/dto/purchase_options_builder.dart'; @@ -35,6 +37,10 @@ export 'src/dto/user_properties.dart'; export 'src/dto/user_property.dart'; export 'src/dto/user_property_key.dart'; export 'src/dto/sk_product/discount_payment_mode.dart'; +export 'src/dto/sk_product/sk_payment_discount.dart'; +export 'src/dto/sk_product/sk_product.dart'; +export 'src/dto/sk_product/sk_product_discount.dart'; +export 'src/dto/sk_product/subscription_period.dart'; export 'src/dto/sk_product/subscription_period_unit.dart'; export 'src/dto/sku_details/sku_details.dart'; export 'src/dto/store_product/product_inapp_details.dart'; diff --git a/lib/src/dto/automations/action_result.g.dart b/lib/src/dto/automations/action_result.g.dart index d1b711f5..ae5ecd23 100644 --- a/lib/src/dto/automations/action_result.g.dart +++ b/lib/src/dto/automations/action_result.g.dart @@ -6,61 +6,22 @@ part of 'action_result.dart'; // JsonSerializableGenerator // ************************************************************************** -ActionResult _$ActionResultFromJson(Map json) { - return ActionResult( - _$enumDecodeNullable(_$ActionResultTypeEnumMap, json['type']) ?? - ActionResultType.unknown, - (json['value'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ), - QMapper.qonversionErrorFromJson(json['error']), - ); -} +ActionResult _$ActionResultFromJson(Map json) => ActionResult( + $enumDecodeNullable(_$ActionResultTypeEnumMap, json['type']) ?? + ActionResultType.unknown, + (json['value'] as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + QMapper.qonversionErrorFromJson(json['error']), + ); Map _$ActionResultToJson(ActionResult instance) => { - 'type': _$ActionResultTypeEnumMap[instance.type], + 'type': _$ActionResultTypeEnumMap[instance.type]!, 'value': instance.parameters, 'error': instance.error, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - -K? _$enumDecodeNullable( - Map enumValues, - dynamic source, { - K? unknownValue, -}) { - if (source == null) { - return null; - } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); -} - const _$ActionResultTypeEnumMap = { ActionResultType.unknown: 'unknown', ActionResultType.url: 'url', diff --git a/lib/src/dto/automations/event.g.dart b/lib/src/dto/automations/event.g.dart index ae8f5f4f..3d30902e 100644 --- a/lib/src/dto/automations/event.g.dart +++ b/lib/src/dto/automations/event.g.dart @@ -6,46 +6,19 @@ part of 'event.dart'; // JsonSerializableGenerator // ************************************************************************** -AutomationsEvent _$AutomationsEventFromJson(Map json) { - return AutomationsEvent( - _$enumDecode(_$AutomationsEventTypeEnumMap, json['type'], - unknownValue: AutomationsEventType.unknown), - QMapper.dateTimeFromSecondsTimestamp(json['timestamp'] as num), - ); -} +AutomationsEvent _$AutomationsEventFromJson(Map json) => + AutomationsEvent( + $enumDecode(_$AutomationsEventTypeEnumMap, json['type'], + unknownValue: AutomationsEventType.unknown), + QMapper.dateTimeFromSecondsTimestamp(json['timestamp'] as num), + ); Map _$AutomationsEventToJson(AutomationsEvent instance) => { - 'type': _$AutomationsEventTypeEnumMap[instance.type], + 'type': _$AutomationsEventTypeEnumMap[instance.type]!, 'timestamp': instance.date.toIso8601String(), }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$AutomationsEventTypeEnumMap = { AutomationsEventType.unknown: 'unknown', AutomationsEventType.trialStarted: 'trial_started', diff --git a/lib/src/dto/eligibility.g.dart b/lib/src/dto/eligibility.g.dart index cfda1155..179a281a 100644 --- a/lib/src/dto/eligibility.g.dart +++ b/lib/src/dto/eligibility.g.dart @@ -6,49 +6,10 @@ part of 'eligibility.dart'; // JsonSerializableGenerator // ************************************************************************** -QEligibility _$QEligibilityFromJson(Map json) { - return QEligibility( - _$enumDecodeNullable(_$QEligibilityStatusEnumMap, json['status']) ?? - QEligibilityStatus.unknown, - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', +QEligibility _$QEligibilityFromJson(Map json) => QEligibility( + $enumDecodeNullable(_$QEligibilityStatusEnumMap, json['status']) ?? + QEligibilityStatus.unknown, ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - -K? _$enumDecodeNullable( - Map enumValues, - dynamic source, { - K? unknownValue, -}) { - if (source == null) { - return null; - } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); -} const _$QEligibilityStatusEnumMap = { QEligibilityStatus.unknown: 'unknown', diff --git a/lib/src/dto/entitlement.g.dart b/lib/src/dto/entitlement.g.dart index 954326f0..0c08f27a 100644 --- a/lib/src/dto/entitlement.g.dart +++ b/lib/src/dto/entitlement.g.dart @@ -6,59 +6,31 @@ part of 'entitlement.dart'; // JsonSerializableGenerator // ************************************************************************** -QEntitlement _$QEntitlementFromJson(Map json) { - return QEntitlement( - json['id'] as String, - json['productId'] as String, - _$enumDecode(_$QEntitlementRenewStateEnumMap, json['renewState'], - unknownValue: QEntitlementRenewState.unknown), - _$enumDecode(_$QEntitlementSourceEnumMap, json['source'], - unknownValue: QEntitlementSource.unknown), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['startedTimestamp'] as num?), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['expirationTimestamp'] as num?), - json['active'] as bool, - json['renewsCount'] as int? ?? 0, - QMapper.dateTimeFromNullableSecondsTimestamp( - json['trialStartTimestamp'] as num?), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['firstPurchaseTimestamp'] as num?), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['lastPurchaseTimestamp'] as num?), - json['lastActivatedOfferCode'] as String?, - QMapper.grantTypeFromNullableValue(json['grantType'] as String?), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['autoRenewDisableTimestamp'] as num?), - QMapper.transactionsFromNullableValue(json['transactions'] as List?), - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', +QEntitlement _$QEntitlementFromJson(Map json) => QEntitlement( + json['id'] as String, + json['productId'] as String, + $enumDecode(_$QEntitlementRenewStateEnumMap, json['renewState'], + unknownValue: QEntitlementRenewState.unknown), + $enumDecode(_$QEntitlementSourceEnumMap, json['source'], + unknownValue: QEntitlementSource.unknown), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['startedTimestamp'] as num?), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['expirationTimestamp'] as num?), + json['active'] as bool, + (json['renewsCount'] as num?)?.toInt() ?? 0, + QMapper.dateTimeFromNullableSecondsTimestamp( + json['trialStartTimestamp'] as num?), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['firstPurchaseTimestamp'] as num?), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['lastPurchaseTimestamp'] as num?), + json['lastActivatedOfferCode'] as String?, + QMapper.grantTypeFromNullableValue(json['grantType'] as String?), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['autoRenewDisableTimestamp'] as num?), + QMapper.transactionsFromNullableValue(json['transactions'] as List?), ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} const _$QEntitlementRenewStateEnumMap = { QEntitlementRenewState.nonRenewable: 'non_renewable', diff --git a/lib/src/dto/experiment.g.dart b/lib/src/dto/experiment.g.dart index 96c1551b..5c47b5f2 100644 --- a/lib/src/dto/experiment.g.dart +++ b/lib/src/dto/experiment.g.dart @@ -6,10 +6,8 @@ part of 'experiment.dart'; // JsonSerializableGenerator // ************************************************************************** -QExperiment _$QExperimentFromJson(Map json) { - return QExperiment( - json['id'] as String, - json['name'] as String, - QExperimentGroup.fromJson(json['group'] as Map), - ); -} +QExperiment _$QExperimentFromJson(Map json) => QExperiment( + json['id'] as String, + json['name'] as String, + QExperimentGroup.fromJson(json['group'] as Map), + ); diff --git a/lib/src/dto/experiment_group.g.dart b/lib/src/dto/experiment_group.g.dart index 2acc3408..354e84e5 100644 --- a/lib/src/dto/experiment_group.g.dart +++ b/lib/src/dto/experiment_group.g.dart @@ -6,40 +6,13 @@ part of 'experiment_group.dart'; // JsonSerializableGenerator // ************************************************************************** -QExperimentGroup _$QExperimentGroupFromJson(Map json) { - return QExperimentGroup( - json['id'] as String, - json['name'] as String, - _$enumDecode(_$QExperimentGroupTypeEnumMap, json['type'], - unknownValue: QExperimentGroupType.unknown), - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', +QExperimentGroup _$QExperimentGroupFromJson(Map json) => + QExperimentGroup( + json['id'] as String, + json['name'] as String, + $enumDecode(_$QExperimentGroupTypeEnumMap, json['type'], + unknownValue: QExperimentGroupType.unknown), ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} const _$QExperimentGroupTypeEnumMap = { QExperimentGroupType.unknown: 'unknown', diff --git a/lib/src/dto/offerings.g.dart b/lib/src/dto/offerings.g.dart index 4d8bf037..1eb871e5 100644 --- a/lib/src/dto/offerings.g.dart +++ b/lib/src/dto/offerings.g.dart @@ -6,52 +6,22 @@ part of 'offerings.dart'; // JsonSerializableGenerator // ************************************************************************** -QOfferings _$QOfferingsFromJson(Map json) { - return QOfferings( - json['main'] == null - ? null - : QOffering.fromJson(json['main'] as Map), - (json['availableOfferings'] as List) - .map((e) => QOffering.fromJson(e as Map)) - .toList(), - ); -} - -QOffering _$QOfferingFromJson(Map json) { - return QOffering( - json['id'] as String, - _$enumDecode(_$QOfferingTagEnumMap, json['tag']), - (json['products'] as List) - .map((e) => QProduct.fromJson(e as Map)) - .toList(), - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', +QOfferings _$QOfferingsFromJson(Map json) => QOfferings( + json['main'] == null + ? null + : QOffering.fromJson(json['main'] as Map), + (json['availableOfferings'] as List) + .map((e) => QOffering.fromJson(e as Map)) + .toList(), ); - } - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} +QOffering _$QOfferingFromJson(Map json) => QOffering( + json['id'] as String, + $enumDecode(_$QOfferingTagEnumMap, json['tag']), + (json['products'] as List) + .map((e) => QProduct.fromJson(e as Map)) + .toList(), + ); const _$QOfferingTagEnumMap = { QOfferingTag.unknown: -1, diff --git a/lib/src/dto/product.dart b/lib/src/dto/product.dart index 1e5bbc6b..0c0af940 100644 --- a/lib/src/dto/product.dart +++ b/lib/src/dto/product.dart @@ -7,9 +7,9 @@ import '../internal/constants.dart'; import 'product_type.dart'; import 'purchase_model.dart'; import 'purchase_update_model.dart'; -import 'sk_product/sk_product_wrapper.dart'; +import 'sk_product/sk_product.dart'; import 'sku_details/sku_details.dart'; -import 'sk_product/discount.dart'; +import 'sk_product/sk_product_discount.dart'; import '../internal/mapper.dart'; import 'subscription_period.dart'; import '../qonversion.dart'; @@ -51,7 +51,7 @@ class QProduct { /// /// Available for iOS only. @JsonKey(name: 'skProduct', fromJson: QMapper.skProductFromJson) - final SKProductWrapper? skProduct; + final SKProduct? skProduct; /// Associated Offering Id @JsonKey(name: 'offeringId') @@ -125,7 +125,7 @@ class QProduct { currencyCode = skProduct.priceLocale?.currencyCode; price = double.tryParse(skProduct.price) ?? null; - final SKProductDiscountWrapper? introPrice = skProduct.introductoryPrice; + final SKProductDiscount? introPrice = skProduct.introductoryPrice; final String? currencySymbol = introPrice?.priceLocale?.currencySymbol; if (introPrice != null && currencySymbol != null) { prettyIntroductoryPrice = currencySymbol + introPrice.price; diff --git a/lib/src/dto/product.g.dart b/lib/src/dto/product.g.dart index 05f3dfd7..5d3cd7ff 100644 --- a/lib/src/dto/product.g.dart +++ b/lib/src/dto/product.g.dart @@ -6,22 +6,20 @@ part of 'product.dart'; // JsonSerializableGenerator // ************************************************************************** -QProduct _$QProductFromJson(Map json) { - return QProduct( - json['id'] as String, - json['storeId'] as String?, - json['basePlanId'] as String?, - QMapper.skuDetailsFromJson(json['skuDetails']), - QMapper.storeProductDetailsFromJson(json['storeDetails']), - QMapper.skProductFromJson(json['skProduct']), - json['offeringId'] as String?, - QMapper.subscriptionPeriodFromJson(json['subscriptionPeriod']), - QMapper.subscriptionPeriodFromJson(json['trialPeriod']), - _$enumDecode(_$QProductTypeEnumMap, json['type'], - unknownValue: QProductType.unknown), - json['prettyPrice'] as String?, - ); -} +QProduct _$QProductFromJson(Map json) => QProduct( + json['id'] as String, + json['storeId'] as String?, + json['basePlanId'] as String?, + QMapper.skuDetailsFromJson(json['skuDetails']), + QMapper.storeProductDetailsFromJson(json['storeDetails']), + QMapper.skProductFromJson(json['skProduct']), + json['offeringId'] as String?, + QMapper.subscriptionPeriodFromJson(json['subscriptionPeriod']), + QMapper.subscriptionPeriodFromJson(json['trialPeriod']), + $enumDecode(_$QProductTypeEnumMap, json['type'], + unknownValue: QProductType.unknown), + json['prettyPrice'] as String?, + ); Map _$QProductToJson(QProduct instance) => { 'id': instance.qonversionId, @@ -33,36 +31,10 @@ Map _$QProductToJson(QProduct instance) => { 'offeringId': instance.offeringId, 'subscriptionPeriod': instance.subscriptionPeriod, 'trialPeriod': instance.trialPeriod, - 'type': _$QProductTypeEnumMap[instance.type], + 'type': _$QProductTypeEnumMap[instance.type]!, 'prettyPrice': instance.prettyPrice, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$QProductTypeEnumMap = { QProductType.trial: 'Trial', QProductType.intro: 'Intro', diff --git a/lib/src/dto/promotional_offer.dart b/lib/src/dto/promotional_offer.dart new file mode 100644 index 00000000..46e1672d --- /dev/null +++ b/lib/src/dto/promotional_offer.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:qonversion_flutter/qonversion_flutter.dart'; + +import '../internal/mapper.dart'; + +part 'promotional_offer.g.dart'; + +@JsonSerializable() +class QPromotionalOffer { + + @JsonKey(fromJson: QMapper.requiredSkProductDiscountFromJson) + final SKProductDiscount productDiscount; + + @JsonKey(fromJson: QMapper.skPaymentDiscountFromJson) + final SKPaymentDiscount paymentDiscount; + + QPromotionalOffer(this.productDiscount, this.paymentDiscount); + + factory QPromotionalOffer.fromJson(Map json) => + _$QPromotionalOfferFromJson(json); + + Map toJson() => _$QPromotionalOfferToJson(this); +} diff --git a/lib/src/dto/promotional_offer.g.dart b/lib/src/dto/promotional_offer.g.dart new file mode 100644 index 00000000..dacdca4c --- /dev/null +++ b/lib/src/dto/promotional_offer.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'promotional_offer.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +QPromotionalOffer _$QPromotionalOfferFromJson(Map json) => + QPromotionalOffer( + QMapper.requiredSkProductDiscountFromJson(json['productDiscount']), + QMapper.skPaymentDiscountFromJson(json['paymentDiscount']), + ); + +Map _$QPromotionalOfferToJson(QPromotionalOffer instance) => + { + 'productDiscount': instance.productDiscount, + 'paymentDiscount': instance.paymentDiscount, + }; diff --git a/lib/src/dto/purchase_options.dart b/lib/src/dto/purchase_options.dart index 20bcffda..973b0cc4 100644 --- a/lib/src/dto/purchase_options.dart +++ b/lib/src/dto/purchase_options.dart @@ -1,6 +1,4 @@ -import 'product.dart'; -import 'purchase_update_policy.dart'; -import 'purchase_options_builder.dart'; +import 'package:qonversion_flutter/qonversion_flutter.dart'; /// Purchase options that may be used to modify purchase process. /// To create an instance, use [QPurchaseOptionsBuilder] class. @@ -11,6 +9,15 @@ class QPurchaseOptions { final QPurchaseUpdatePolicy? updatePolicy; final List? contextKeys; final int quantity; + final QPromotionalOffer? promotionalOffer; - QPurchaseOptions(this.offerId, this.applyOffer, this.oldProduct, this.updatePolicy, this.contextKeys, this.quantity); + QPurchaseOptions( + this.offerId, + this.applyOffer, + this.oldProduct, + this.updatePolicy, + this.contextKeys, + this.quantity, + this.promotionalOffer, + ); } \ No newline at end of file diff --git a/lib/src/dto/purchase_options_builder.dart b/lib/src/dto/purchase_options_builder.dart index 32cf2a07..87bda081 100644 --- a/lib/src/dto/purchase_options_builder.dart +++ b/lib/src/dto/purchase_options_builder.dart @@ -1,4 +1,5 @@ import 'product.dart'; +import 'promotional_offer.dart'; import 'purchase_options.dart'; import 'purchase_update_policy.dart'; import 'store_product/product_offer_details.dart'; @@ -11,6 +12,7 @@ class QPurchaseOptionsBuilder { QPurchaseUpdatePolicy? _updatePolicy; List? _contextKeys; int _quantity = 1; + QPromotionalOffer? _promotionalOffer; /// Android only. /// Set the offer to the purchase. @@ -86,11 +88,20 @@ class QPurchaseOptionsBuilder { return this; } + /// Set the promotional offer details. + /// + /// [promotionalOffer] promotional offer details. + /// Returns builder instance for chain calls. + QPurchaseOptionsBuilder setPromotionalOffer(QPromotionalOffer promotionalOffer) { + _promotionalOffer = promotionalOffer; + return this; + } + /// Generate [QPurchaseOptions] instance with all the provided options. /// /// Returns the complete [QPurchaseOptions] instance. QPurchaseOptions build() { - return QPurchaseOptions(_offerId, _applyOffer, _oldProduct, _updatePolicy, _contextKeys, _quantity); + return QPurchaseOptions(_offerId, _applyOffer, _oldProduct, _updatePolicy, _contextKeys, _quantity, _promotionalOffer); } } \ No newline at end of file diff --git a/lib/src/dto/qonversion_error.g.dart b/lib/src/dto/qonversion_error.g.dart index 3b25c25b..56141d8e 100644 --- a/lib/src/dto/qonversion_error.g.dart +++ b/lib/src/dto/qonversion_error.g.dart @@ -6,47 +6,19 @@ part of 'qonversion_error.dart'; // JsonSerializableGenerator // ************************************************************************** -QError _$QErrorFromJson(Map json) { - return QError( - _$enumDecode(_$QErrorCodeEnumMap, json['code'], - unknownValue: QErrorCode.unknown), - json['description'] as String, - json['additionalMessage'] as String?, - ); -} +QError _$QErrorFromJson(Map json) => QError( + $enumDecode(_$QErrorCodeEnumMap, json['code'], + unknownValue: QErrorCode.unknown), + json['description'] as String, + json['additionalMessage'] as String?, + ); Map _$QErrorToJson(QError instance) => { - 'code': _$QErrorCodeEnumMap[instance.code], + 'code': _$QErrorCodeEnumMap[instance.code]!, 'description': instance.message, 'additionalMessage': instance.details, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$QErrorCodeEnumMap = { QErrorCode.unknown: 'Unknown', QErrorCode.apiRateLimitExceeded: 'ApiRateLimitExceeded', diff --git a/lib/src/dto/remote_config.g.dart b/lib/src/dto/remote_config.g.dart index b02086fd..8556caf2 100644 --- a/lib/src/dto/remote_config.g.dart +++ b/lib/src/dto/remote_config.g.dart @@ -6,12 +6,12 @@ part of 'remote_config.dart'; // JsonSerializableGenerator // ************************************************************************** -QRemoteConfig _$QRemoteConfigFromJson(Map json) { - return QRemoteConfig( - json['payload'] as Map, - json['experiment'] == null - ? null - : QExperiment.fromJson(json['experiment'] as Map), - QRemoteConfigurationSource.fromJson(json['source'] as Map), - ); -} +QRemoteConfig _$QRemoteConfigFromJson(Map json) => + QRemoteConfig( + json['payload'] as Map, + json['experiment'] == null + ? null + : QExperiment.fromJson(json['experiment'] as Map), + QRemoteConfigurationSource.fromJson( + json['source'] as Map), + ); diff --git a/lib/src/dto/remote_config_list.g.dart b/lib/src/dto/remote_config_list.g.dart index db47345e..ed10091f 100644 --- a/lib/src/dto/remote_config_list.g.dart +++ b/lib/src/dto/remote_config_list.g.dart @@ -6,10 +6,9 @@ part of 'remote_config_list.dart'; // JsonSerializableGenerator // ************************************************************************** -QRemoteConfigList _$QRemoteConfigListFromJson(Map json) { - return QRemoteConfigList( - (json['remoteConfigs'] as List) - .map((e) => QRemoteConfig.fromJson(e as Map)) - .toList(), - ); -} +QRemoteConfigList _$QRemoteConfigListFromJson(Map json) => + QRemoteConfigList( + (json['remoteConfigs'] as List) + .map((e) => QRemoteConfig.fromJson(e as Map)) + .toList(), + ); diff --git a/lib/src/dto/remote_configuration_source.g.dart b/lib/src/dto/remote_configuration_source.g.dart index 8c938e30..e0203c4e 100644 --- a/lib/src/dto/remote_configuration_source.g.dart +++ b/lib/src/dto/remote_configuration_source.g.dart @@ -7,44 +7,17 @@ part of 'remote_configuration_source.dart'; // ************************************************************************** QRemoteConfigurationSource _$QRemoteConfigurationSourceFromJson( - Map json) { - return QRemoteConfigurationSource( - json['id'] as String, - json['name'] as String, - _$enumDecode(_$QRemoteConfigurationSourceTypeEnumMap, json['type'], - unknownValue: QRemoteConfigurationSourceType.unknown), - _$enumDecode( - _$QRemoteConfigurationAssignmentTypeEnumMap, json['assignmentType'], - unknownValue: QRemoteConfigurationAssignmentType.unknown), - json['contextKey'] as String?, - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', + Map json) => + QRemoteConfigurationSource( + json['id'] as String, + json['name'] as String, + $enumDecode(_$QRemoteConfigurationSourceTypeEnumMap, json['type'], + unknownValue: QRemoteConfigurationSourceType.unknown), + $enumDecode( + _$QRemoteConfigurationAssignmentTypeEnumMap, json['assignmentType'], + unknownValue: QRemoteConfigurationAssignmentType.unknown), + json['contextKey'] as String?, ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} const _$QRemoteConfigurationSourceTypeEnumMap = { QRemoteConfigurationSourceType.unknown: 'unknown', diff --git a/lib/src/dto/screen_presentation_config.g.dart b/lib/src/dto/screen_presentation_config.g.dart index e2f5552f..9a05f94e 100644 --- a/lib/src/dto/screen_presentation_config.g.dart +++ b/lib/src/dto/screen_presentation_config.g.dart @@ -10,7 +10,7 @@ Map _$QScreenPresentationConfigToJson( QScreenPresentationConfig instance) => { 'presentationStyle': - _$QScreenPresentationStyleEnumMap[instance.presentationStyle], + _$QScreenPresentationStyleEnumMap[instance.presentationStyle]!, 'animated': animatedToJson(instance.animated), }; diff --git a/lib/src/dto/sk_product/discount.g.dart b/lib/src/dto/sk_product/discount.g.dart deleted file mode 100644 index f26cbc9f..00000000 --- a/lib/src/dto/sk_product/discount.g.dart +++ /dev/null @@ -1,63 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'discount.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SKProductDiscountWrapper _$SKProductDiscountWrapperFromJson( - Map json) { - return SKProductDiscountWrapper( - price: json['price'] as String, - priceLocale: QMapper.skPriceLocaleFromJson(json['priceLocale']), - numberOfPeriods: json['numberOfPeriods'] as int, - paymentMode: _$enumDecode( - _$SKProductDiscountPaymentModeEnumMap, json['paymentMode']), - subscriptionPeriod: - QMapper.skProductSubscriptionPeriodFromJson(json['subscriptionPeriod']), - ); -} - -Map _$SKProductDiscountWrapperToJson( - SKProductDiscountWrapper instance) => - { - 'price': instance.price, - 'priceLocale': instance.priceLocale, - 'numberOfPeriods': instance.numberOfPeriods, - 'paymentMode': - _$SKProductDiscountPaymentModeEnumMap[instance.paymentMode], - 'subscriptionPeriod': instance.subscriptionPeriod, - }; - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - -const _$SKProductDiscountPaymentModeEnumMap = { - SKProductDiscountPaymentMode.payAsYouGo: 0, - SKProductDiscountPaymentMode.payUpFront: 1, - SKProductDiscountPaymentMode.freeTrial: 2, -}; diff --git a/lib/src/dto/sk_product/sk_payment_discount.dart b/lib/src/dto/sk_product/sk_payment_discount.dart new file mode 100644 index 00000000..3dd9dcef --- /dev/null +++ b/lib/src/dto/sk_product/sk_payment_discount.dart @@ -0,0 +1,42 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'sk_payment_discount.g.dart'; + +/// Dart wrapper around StoreKit's [SKPaymentDiscount](https://developer.apple.com/documentation/storekit/skpaymentdiscount?language=objc). +/// +/// It is used as a property in [SKProduct]. +@JsonSerializable() +class SKPaymentDiscount { + /// A string used to uniquely identify a discount offer for a product. + final String identifier; + + /// A string that identifies the key used to generate the signature. + final String keyIdentifier; + + /// A universally unique ID (UUID) value that you define. + final String nonce; + + /// A string representing the properties of a specific promotional offer, cryptographically signed. + final String signature; + + /// The date and time of the signature's creation in milliseconds, formatted in Unix epoch time. + final num timestamp; + + /// Creates an [SKPaymentDiscount] with the given discount details. + SKPaymentDiscount({ + required this.identifier, + required this.keyIdentifier, + required this.nonce, + required this.signature, + required this.timestamp, + }); + + /// Constructing an instance from a map from the Objective-C layer. + /// + /// The `map` parameter must not be null. + factory SKPaymentDiscount.fromJson(Map map) { + return _$SKPaymentDiscountFromJson(map); + } + + Map toJson() => _$SKPaymentDiscountToJson(this); +} diff --git a/lib/src/dto/sk_product/sk_payment_discount.g.dart b/lib/src/dto/sk_product/sk_payment_discount.g.dart new file mode 100644 index 00000000..215cf1eb --- /dev/null +++ b/lib/src/dto/sk_product/sk_payment_discount.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'sk_payment_discount.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SKPaymentDiscount _$SKPaymentDiscountFromJson(Map json) => + SKPaymentDiscount( + identifier: json['identifier'] as String, + keyIdentifier: json['keyIdentifier'] as String, + nonce: json['nonce'] as String, + signature: json['signature'] as String, + timestamp: json['timestamp'] as num, + ); + +Map _$SKPaymentDiscountToJson(SKPaymentDiscount instance) => + { + 'identifier': instance.identifier, + 'keyIdentifier': instance.keyIdentifier, + 'nonce': instance.nonce, + 'signature': instance.signature, + 'timestamp': instance.timestamp, + }; diff --git a/lib/src/dto/sk_product/sk_product_wrapper.dart b/lib/src/dto/sk_product/sk_product.dart similarity index 77% rename from lib/src/dto/sk_product/sk_product_wrapper.dart rename to lib/src/dto/sk_product/sk_product.dart index 8641e9a1..d3f057d3 100644 --- a/lib/src/dto/sk_product/sk_product_wrapper.dart +++ b/lib/src/dto/sk_product/sk_product.dart @@ -3,14 +3,14 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:qonversion_flutter/src/internal/mapper.dart'; -import 'discount.dart'; +import 'sk_product_discount.dart'; import 'subscription_period.dart'; -part 'sk_product_wrapper.g.dart'; +part 'sk_product.g.dart'; /// Dart wrapper around StoreKit's [SKProduct](https://developer.apple.com/documentation/storekit/skproduct?language=objc). @JsonSerializable() -class SKProductWrapper { +class SKProduct { /// The unique identifier of the product. final String productIdentifier; @@ -26,7 +26,7 @@ class SKProductWrapper { /// Includes locale information about the price, e.g. `$` as the currency symbol for US locale. @JsonKey(fromJson: QMapper.skPriceLocaleFromJson) - final SKPriceLocaleWrapper? priceLocale; + final SKPriceLocale? priceLocale; /// The subscription group identifier. /// @@ -41,7 +41,7 @@ class SKProductWrapper { /// /// Can be [null] is the product is not a subscription. @JsonKey(fromJson: QMapper.skProductSubscriptionPeriodFromJson) - final SKProductSubscriptionPeriodWrapper? subscriptionPeriod; + final SKProductSubscriptionPeriod? subscriptionPeriod; /// The object represents the duration of single subscription period. /// @@ -51,10 +51,16 @@ class SKProductWrapper { /// The [subscriptionPeriod] of the discount is independent of the product's [subscriptionPeriod], /// and their units and duration do not have to be matched. @JsonKey(fromJson: QMapper.skProductDiscountFromJson) - final SKProductDiscountWrapper? introductoryPrice; + final SKProductDiscount? introductoryPrice; - /// Creates an [SKProductWrapper] with the given product details. - const SKProductWrapper({ + @JsonKey(fromJson: QMapper.skProductDiscountFromJson) + final SKProductDiscount? productDiscount; + + @JsonKey(fromJson: QMapper.skProductDiscountsFromList) + final List? discounts; + + /// Creates an [SKProduct] with the given product details. + const SKProduct({ required this.productIdentifier, required this.localizedTitle, required this.localizedDescription, @@ -63,12 +69,14 @@ class SKProductWrapper { required this.price, required this.subscriptionPeriod, required this.introductoryPrice, + this.productDiscount, + this.discounts, }); - factory SKProductWrapper.fromJson(Map json) => - _$SKProductWrapperFromJson(json); + factory SKProduct.fromJson(Map json) => + _$SKProductFromJson(json); - Map toJson() => _$SKProductWrapperToJson(this); + Map toJson() => _$SKProductToJson(this); @override bool operator ==(Object other) { @@ -78,7 +86,7 @@ class SKProductWrapper { if (other.runtimeType != runtimeType) { return false; } - return other is SKProductWrapper && + return other is SKProduct && other.productIdentifier == productIdentifier && other.localizedTitle == localizedTitle && other.localizedDescription == localizedDescription && @@ -86,7 +94,9 @@ class SKProductWrapper { other.subscriptionGroupIdentifier == subscriptionGroupIdentifier && other.price == price && other.subscriptionPeriod == subscriptionPeriod && - other.introductoryPrice == introductoryPrice; + other.introductoryPrice == introductoryPrice && + other.productDiscount == productDiscount && + other.discounts == discounts; } @override @@ -98,14 +108,16 @@ class SKProductWrapper { this.subscriptionGroupIdentifier, this.price, this.subscriptionPeriod, - this.introductoryPrice); + this.introductoryPrice, + this.productDiscount, + this.discounts); } /// Object that indicates the locale of the price /// /// It is a thin wrapper of [NSLocale](https://developer.apple.com/documentation/foundation/nslocale?language=objc). @JsonSerializable() -class SKPriceLocaleWrapper { +class SKPriceLocale { ///The currency symbol for the locale, e.g. $ for US locale. final String? currencySymbol; @@ -113,15 +125,15 @@ class SKPriceLocaleWrapper { final String? currencyCode; /// Creates a new price locale for `currencySymbol` and `currencyCode`. - const SKPriceLocaleWrapper({ + const SKPriceLocale({ required this.currencySymbol, required this.currencyCode, }); - factory SKPriceLocaleWrapper.fromJson(Map json) => - _$SKPriceLocaleWrapperFromJson(json); + factory SKPriceLocale.fromJson(Map json) => + _$SKPriceLocaleFromJson(json); - Map toJson() => _$SKPriceLocaleWrapperToJson(this); + Map toJson() => _$SKPriceLocaleToJson(this); @override bool operator ==(Object other) { @@ -131,7 +143,7 @@ class SKPriceLocaleWrapper { if (other.runtimeType != runtimeType) { return false; } - return other is SKPriceLocaleWrapper && + return other is SKPriceLocale && other.currencySymbol == currencySymbol && other.currencyCode == currencyCode; } diff --git a/lib/src/dto/sk_product/sk_product.g.dart b/lib/src/dto/sk_product/sk_product.g.dart new file mode 100644 index 00000000..e7bc2902 --- /dev/null +++ b/lib/src/dto/sk_product/sk_product.g.dart @@ -0,0 +1,49 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'sk_product.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SKProduct _$SKProductFromJson(Map json) => SKProduct( + productIdentifier: json['productIdentifier'] as String, + localizedTitle: json['localizedTitle'] as String?, + localizedDescription: json['localizedDescription'] as String?, + priceLocale: QMapper.skPriceLocaleFromJson(json['priceLocale']), + subscriptionGroupIdentifier: + json['subscriptionGroupIdentifier'] as String?, + price: json['price'] as String, + subscriptionPeriod: QMapper.skProductSubscriptionPeriodFromJson( + json['subscriptionPeriod']), + introductoryPrice: + QMapper.skProductDiscountFromJson(json['introductoryPrice']), + productDiscount: + QMapper.skProductDiscountFromJson(json['productDiscount']), + discounts: QMapper.skProductDiscountsFromList(json['discounts'] as List?), + ); + +Map _$SKProductToJson(SKProduct instance) => { + 'productIdentifier': instance.productIdentifier, + 'localizedTitle': instance.localizedTitle, + 'localizedDescription': instance.localizedDescription, + 'priceLocale': instance.priceLocale, + 'subscriptionGroupIdentifier': instance.subscriptionGroupIdentifier, + 'price': instance.price, + 'subscriptionPeriod': instance.subscriptionPeriod, + 'introductoryPrice': instance.introductoryPrice, + 'productDiscount': instance.productDiscount, + 'discounts': instance.discounts, + }; + +SKPriceLocale _$SKPriceLocaleFromJson(Map json) => + SKPriceLocale( + currencySymbol: json['currencySymbol'] as String?, + currencyCode: json['currencyCode'] as String?, + ); + +Map _$SKPriceLocaleToJson(SKPriceLocale instance) => + { + 'currencySymbol': instance.currencySymbol, + 'currencyCode': instance.currencyCode, + }; diff --git a/lib/src/dto/sk_product/discount.dart b/lib/src/dto/sk_product/sk_product_discount.dart similarity index 73% rename from lib/src/dto/sk_product/discount.dart rename to lib/src/dto/sk_product/sk_product_discount.dart index cb1d5913..42018b7c 100644 --- a/lib/src/dto/sk_product/discount.dart +++ b/lib/src/dto/sk_product/sk_product_discount.dart @@ -2,22 +2,24 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:qonversion_flutter/src/internal/mapper.dart'; import 'discount_payment_mode.dart'; -import 'sk_product_wrapper.dart'; +import 'sk_product.dart'; import 'subscription_period.dart'; -part 'discount.g.dart'; +part 'sk_product_discount.g.dart'; /// Dart wrapper around StoreKit's [SKProductDiscount](https://developer.apple.com/documentation/storekit/skproductdiscount?language=objc). /// -/// It is used as a property in [SKProductWrapper]. +/// It is used as a property in [SKProduct]. @JsonSerializable() -class SKProductDiscountWrapper { +class SKProductDiscount { + final String? identifier; + /// The discounted price, in the currency that is defined in [priceLocale]. final String price; /// Includes locale information about the price, e.g. `$` as the currency symbol for US locale. @JsonKey(fromJson: QMapper.skPriceLocaleFromJson) - final SKPriceLocaleWrapper? priceLocale; + final SKPriceLocale? priceLocale; /// The object represent the discount period length. /// @@ -32,10 +34,11 @@ class SKProductDiscountWrapper { /// The [subscriptionPeriod] of the discount is independent of the product's [subscriptionPeriod], /// and their units and duration do not have to be matched. @JsonKey(fromJson: QMapper.skProductSubscriptionPeriodFromJson) - final SKProductSubscriptionPeriodWrapper? subscriptionPeriod; + final SKProductSubscriptionPeriod? subscriptionPeriod; - /// Creates an [SKProductDiscountWrapper] with the given discount details. - SKProductDiscountWrapper({ + /// Creates an [SKProductDiscount] with the given discount details. + SKProductDiscount({ + required this.identifier, required this.price, required this.priceLocale, required this.numberOfPeriods, @@ -45,13 +48,13 @@ class SKProductDiscountWrapper { /// Constructing an instance from a map from the Objective-C layer. /// - /// This method should only be used with `map` values returned by [SKProductWrapper.fromJson]. + /// This method should only be used with `map` values returned by [SKProduct.fromJson]. /// The `map` parameter must not be null. - factory SKProductDiscountWrapper.fromJson(Map map) { - return _$SKProductDiscountWrapperFromJson(map); + factory SKProductDiscount.fromJson(Map map) { + return _$SKProductDiscountFromJson(map); } - Map toJson() => _$SKProductDiscountWrapperToJson(this); + Map toJson() => _$SKProductDiscountToJson(this); @override bool operator ==(Object other) { @@ -61,7 +64,8 @@ class SKProductDiscountWrapper { if (other.runtimeType != runtimeType) { return false; } - return other is SKProductDiscountWrapper && + return other is SKProductDiscount && + other.identifier == identifier && other.price == price && other.priceLocale == priceLocale && other.numberOfPeriods == numberOfPeriods && @@ -70,6 +74,6 @@ class SKProductDiscountWrapper { } @override - int get hashCode => Object.hash(this.price, this.priceLocale, + int get hashCode => Object.hash(this.identifier, this.price, this.priceLocale, this.numberOfPeriods, this.paymentMode, this.subscriptionPeriod); } diff --git a/lib/src/dto/sk_product/sk_product_discount.g.dart b/lib/src/dto/sk_product/sk_product_discount.g.dart new file mode 100644 index 00000000..f3593c45 --- /dev/null +++ b/lib/src/dto/sk_product/sk_product_discount.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'sk_product_discount.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SKProductDiscount _$SKProductDiscountFromJson(Map json) => + SKProductDiscount( + identifier: json['identifier'] as String?, + price: json['price'] as String, + priceLocale: QMapper.skPriceLocaleFromJson(json['priceLocale']), + numberOfPeriods: (json['numberOfPeriods'] as num).toInt(), + paymentMode: $enumDecode( + _$SKProductDiscountPaymentModeEnumMap, json['paymentMode']), + subscriptionPeriod: QMapper.skProductSubscriptionPeriodFromJson( + json['subscriptionPeriod']), + ); + +Map _$SKProductDiscountToJson(SKProductDiscount instance) => + { + 'identifier': instance.identifier, + 'price': instance.price, + 'priceLocale': instance.priceLocale, + 'numberOfPeriods': instance.numberOfPeriods, + 'paymentMode': + _$SKProductDiscountPaymentModeEnumMap[instance.paymentMode]!, + 'subscriptionPeriod': instance.subscriptionPeriod, + }; + +const _$SKProductDiscountPaymentModeEnumMap = { + SKProductDiscountPaymentMode.payAsYouGo: 0, + SKProductDiscountPaymentMode.payUpFront: 1, + SKProductDiscountPaymentMode.freeTrial: 2, +}; diff --git a/lib/src/dto/sk_product/sk_product_wrapper.g.dart b/lib/src/dto/sk_product/sk_product_wrapper.g.dart deleted file mode 100644 index fc3e5387..00000000 --- a/lib/src/dto/sk_product/sk_product_wrapper.g.dart +++ /dev/null @@ -1,48 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'sk_product_wrapper.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SKProductWrapper _$SKProductWrapperFromJson(Map json) { - return SKProductWrapper( - productIdentifier: json['productIdentifier'] as String, - localizedTitle: json['localizedTitle'] as String?, - localizedDescription: json['localizedDescription'] as String?, - priceLocale: QMapper.skPriceLocaleFromJson(json['priceLocale']), - subscriptionGroupIdentifier: json['subscriptionGroupIdentifier'] as String?, - price: json['price'] as String, - subscriptionPeriod: - QMapper.skProductSubscriptionPeriodFromJson(json['subscriptionPeriod']), - introductoryPrice: - QMapper.skProductDiscountFromJson(json['introductoryPrice']), - ); -} - -Map _$SKProductWrapperToJson(SKProductWrapper instance) => - { - 'productIdentifier': instance.productIdentifier, - 'localizedTitle': instance.localizedTitle, - 'localizedDescription': instance.localizedDescription, - 'priceLocale': instance.priceLocale, - 'subscriptionGroupIdentifier': instance.subscriptionGroupIdentifier, - 'price': instance.price, - 'subscriptionPeriod': instance.subscriptionPeriod, - 'introductoryPrice': instance.introductoryPrice, - }; - -SKPriceLocaleWrapper _$SKPriceLocaleWrapperFromJson(Map json) { - return SKPriceLocaleWrapper( - currencySymbol: json['currencySymbol'] as String?, - currencyCode: json['currencyCode'] as String?, - ); -} - -Map _$SKPriceLocaleWrapperToJson( - SKPriceLocaleWrapper instance) => - { - 'currencySymbol': instance.currencySymbol, - 'currencyCode': instance.currencyCode, - }; diff --git a/lib/src/dto/sk_product/subscription_period.dart b/lib/src/dto/sk_product/subscription_period.dart index a7734039..e75ecb88 100644 --- a/lib/src/dto/sk_product/subscription_period.dart +++ b/lib/src/dto/sk_product/subscription_period.dart @@ -9,8 +9,8 @@ part 'subscription_period.g.dart'; /// A period is defined by a [numberOfUnits] and a [unit], e.g for a 3 months period [numberOfUnits] is 3 and [unit] is a month. /// It is used as a property in [SKProductDiscountWrapper] and [SKProductWrapper]. @JsonSerializable() -class SKProductSubscriptionPeriodWrapper { - /// Creates an [SKProductSubscriptionPeriodWrapper] for a `numberOfUnits`x`unit` period. +class SKProductSubscriptionPeriod { + /// Creates an [SKProductSubscriptionPeriod] for a `numberOfUnits`x`unit` period. /// The number of [unit] units in this period. /// @@ -20,22 +20,22 @@ class SKProductSubscriptionPeriodWrapper { /// The time unit used to specify the length of this period. final SKSubscriptionPeriodUnit unit; - SKProductSubscriptionPeriodWrapper({ + SKProductSubscriptionPeriod({ required this.numberOfUnits, required this.unit, }); /// Constructing an instance from a map from the Objective-C layer. /// - /// This method should only be used with `map` values returned by [SKProductDiscountWrapper.fromJson] or [SKProductWrapper.fromJson]. + /// This method should only be used with `map` values returned by [SKProductDiscount.fromJson] or [SKProduct.fromJson]. /// The `map` parameter must not be null. - factory SKProductSubscriptionPeriodWrapper.fromJson( + factory SKProductSubscriptionPeriod.fromJson( Map map) { - return _$SKProductSubscriptionPeriodWrapperFromJson(map); + return _$SKProductSubscriptionPeriodFromJson(map); } Map toJson() => - _$SKProductSubscriptionPeriodWrapperToJson(this); + _$SKProductSubscriptionPeriodToJson(this); @override bool operator ==(Object other) { @@ -45,7 +45,7 @@ class SKProductSubscriptionPeriodWrapper { if (other.runtimeType != runtimeType) { return false; } - return other is SKProductSubscriptionPeriodWrapper && + return other is SKProductSubscriptionPeriod && other.numberOfUnits == numberOfUnits && other.unit == unit; } diff --git a/lib/src/dto/sk_product/subscription_period.g.dart b/lib/src/dto/sk_product/subscription_period.g.dart index 732d602f..feba44c8 100644 --- a/lib/src/dto/sk_product/subscription_period.g.dart +++ b/lib/src/dto/sk_product/subscription_period.g.dart @@ -6,47 +6,20 @@ part of 'subscription_period.dart'; // JsonSerializableGenerator // ************************************************************************** -SKProductSubscriptionPeriodWrapper _$SKProductSubscriptionPeriodWrapperFromJson( - Map json) { - return SKProductSubscriptionPeriodWrapper( - numberOfUnits: json['numberOfUnits'] as int, - unit: _$enumDecode(_$SKSubscriptionPeriodUnitEnumMap, json['unit']), - ); -} +SKProductSubscriptionPeriod _$SKProductSubscriptionPeriodFromJson( + Map json) => + SKProductSubscriptionPeriod( + numberOfUnits: (json['numberOfUnits'] as num).toInt(), + unit: $enumDecode(_$SKSubscriptionPeriodUnitEnumMap, json['unit']), + ); -Map _$SKProductSubscriptionPeriodWrapperToJson( - SKProductSubscriptionPeriodWrapper instance) => +Map _$SKProductSubscriptionPeriodToJson( + SKProductSubscriptionPeriod instance) => { 'numberOfUnits': instance.numberOfUnits, - 'unit': _$SKSubscriptionPeriodUnitEnumMap[instance.unit], + 'unit': _$SKSubscriptionPeriodUnitEnumMap[instance.unit]!, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$SKSubscriptionPeriodUnitEnumMap = { SKSubscriptionPeriodUnit.day: 0, SKSubscriptionPeriodUnit.week: 1, diff --git a/lib/src/dto/sku_details/sku_details.g.dart b/lib/src/dto/sku_details/sku_details.g.dart index 398a4e0a..b4d728fc 100644 --- a/lib/src/dto/sku_details/sku_details.g.dart +++ b/lib/src/dto/sku_details/sku_details.g.dart @@ -6,30 +6,28 @@ part of 'sku_details.dart'; // JsonSerializableGenerator // ************************************************************************** -// ignore: deprecated_member_use_from_same_package -SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) { - // ignore: deprecated_member_use_from_same_package - return SkuDetailsWrapper( - description: json['description'] as String, - freeTrialPeriod: json['freeTrialPeriod'] as String, - introductoryPrice: json['introductoryPrice'] as String, - introductoryPriceAmountMicros: json['introductoryPriceAmountMicros'] as int, - introductoryPriceCycles: json['introductoryPriceCycles'] as int, - introductoryPricePeriod: json['introductoryPricePeriod'] as String, - price: json['price'] as String, - priceAmountMicros: json['priceAmountMicros'] as int, - priceCurrencyCode: json['priceCurrencyCode'] as String, - sku: json['sku'] as String, - subscriptionPeriod: json['subscriptionPeriod'] as String, - title: json['title'] as String, - type: _$enumDecode(_$SkuTypeEnumMap, json['type']), - originalPrice: json['originalPrice'] as String, - originalPriceAmountMicros: json['originalPriceAmountMicros'] as int, - originalJson: json['originalJson'] as String, - ); -} +SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) => + SkuDetailsWrapper( + description: json['description'] as String, + freeTrialPeriod: json['freeTrialPeriod'] as String, + introductoryPrice: json['introductoryPrice'] as String, + introductoryPriceAmountMicros: + (json['introductoryPriceAmountMicros'] as num).toInt(), + introductoryPriceCycles: (json['introductoryPriceCycles'] as num).toInt(), + introductoryPricePeriod: json['introductoryPricePeriod'] as String, + price: json['price'] as String, + priceAmountMicros: (json['priceAmountMicros'] as num).toInt(), + priceCurrencyCode: json['priceCurrencyCode'] as String, + sku: json['sku'] as String, + subscriptionPeriod: json['subscriptionPeriod'] as String, + title: json['title'] as String, + type: $enumDecode(_$SkuTypeEnumMap, json['type']), + originalPrice: json['originalPrice'] as String, + originalPriceAmountMicros: + (json['originalPriceAmountMicros'] as num).toInt(), + originalJson: json['originalJson'] as String, + ); -// ignore: deprecated_member_use_from_same_package Map _$SkuDetailsWrapperToJson(SkuDetailsWrapper instance) => { 'description': instance.description, @@ -44,38 +42,12 @@ Map _$SkuDetailsWrapperToJson(SkuDetailsWrapper instance) => 'sku': instance.sku, 'subscriptionPeriod': instance.subscriptionPeriod, 'title': instance.title, - 'type': _$SkuTypeEnumMap[instance.type], + 'type': _$SkuTypeEnumMap[instance.type]!, 'originalPrice': instance.originalPrice, 'originalPriceAmountMicros': instance.originalPriceAmountMicros, 'originalJson': instance.originalJson, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$SkuTypeEnumMap = { SkuType.inapp: 'inapp', SkuType.subs: 'subs', diff --git a/lib/src/dto/store_product/product_inapp_details.g.dart b/lib/src/dto/store_product/product_inapp_details.g.dart index f7d8aad3..4ba654ec 100644 --- a/lib/src/dto/store_product/product_inapp_details.g.dart +++ b/lib/src/dto/store_product/product_inapp_details.g.dart @@ -6,11 +6,11 @@ part of 'product_inapp_details.dart'; // JsonSerializableGenerator // ************************************************************************** -QProductInAppDetails _$QProductInAppDetailsFromJson(Map json) { - return QProductInAppDetails( - QMapper.requiredProductPriceFromJson(json['price']), - ); -} +QProductInAppDetails _$QProductInAppDetailsFromJson( + Map json) => + QProductInAppDetails( + QMapper.requiredProductPriceFromJson(json['price']), + ); Map _$QProductInAppDetailsToJson( QProductInAppDetails instance) => diff --git a/lib/src/dto/store_product/product_installment_plan_details.g.dart b/lib/src/dto/store_product/product_installment_plan_details.g.dart index 27568411..20135d5c 100644 --- a/lib/src/dto/store_product/product_installment_plan_details.g.dart +++ b/lib/src/dto/store_product/product_installment_plan_details.g.dart @@ -7,12 +7,11 @@ part of 'product_installment_plan_details.dart'; // ************************************************************************** QProductInstallmentPlanDetails _$QProductInstallmentPlanDetailsFromJson( - Map json) { - return QProductInstallmentPlanDetails( - json['commitmentPaymentsCount'] as int, - json['subsequentCommitmentPaymentsCount'] as int, - ); -} + Map json) => + QProductInstallmentPlanDetails( + (json['commitmentPaymentsCount'] as num).toInt(), + (json['subsequentCommitmentPaymentsCount'] as num).toInt(), + ); Map _$QProductInstallmentPlanDetailsToJson( QProductInstallmentPlanDetails instance) => diff --git a/lib/src/dto/store_product/product_offer_details.g.dart b/lib/src/dto/store_product/product_offer_details.g.dart index 7532e83e..6882b043 100644 --- a/lib/src/dto/store_product/product_offer_details.g.dart +++ b/lib/src/dto/store_product/product_offer_details.g.dart @@ -6,23 +6,23 @@ part of 'product_offer_details.dart'; // JsonSerializableGenerator // ************************************************************************** -QProductOfferDetails _$QProductOfferDetailsFromJson(Map json) { - return QProductOfferDetails( - json['basePlanId'] as String, - json['offerId'] as String?, - json['offerToken'] as String, - (json['tags'] as List).map((e) => e as String).toList(), - QMapper.productPricingPhaseListFromJson(json['pricingPhases']), - QMapper.productPricingPhaseFromJson(json['basePlan']), - QMapper.productInstallmentPlanDetailsFromJson( - json['installmentPlanDetails']), - QMapper.productPricingPhaseFromJson(json['introPhase']), - QMapper.productPricingPhaseFromJson(json['trialPhase']), - json['hasTrial'] as bool, - json['hasIntro'] as bool, - json['hasTrialOrIntro'] as bool, - ); -} +QProductOfferDetails _$QProductOfferDetailsFromJson( + Map json) => + QProductOfferDetails( + json['basePlanId'] as String, + json['offerId'] as String?, + json['offerToken'] as String, + (json['tags'] as List).map((e) => e as String).toList(), + QMapper.productPricingPhaseListFromJson(json['pricingPhases']), + QMapper.productPricingPhaseFromJson(json['basePlan']), + QMapper.productInstallmentPlanDetailsFromJson( + json['installmentPlanDetails']), + QMapper.productPricingPhaseFromJson(json['introPhase']), + QMapper.productPricingPhaseFromJson(json['trialPhase']), + json['hasTrial'] as bool, + json['hasIntro'] as bool, + json['hasTrialOrIntro'] as bool, + ); Map _$QProductOfferDetailsToJson( QProductOfferDetails instance) => diff --git a/lib/src/dto/store_product/product_price.g.dart b/lib/src/dto/store_product/product_price.g.dart index 872c8026..3c356e48 100644 --- a/lib/src/dto/store_product/product_price.g.dart +++ b/lib/src/dto/store_product/product_price.g.dart @@ -6,15 +6,14 @@ part of 'product_price.dart'; // JsonSerializableGenerator // ************************************************************************** -QProductPrice _$QProductPriceFromJson(Map json) { - return QProductPrice( - json['priceAmountMicros'] as int, - json['priceCurrencyCode'] as String, - json['formattedPrice'] as String, - json['isFree'] as bool, - json['currencySymbol'] as String?, - ); -} +QProductPrice _$QProductPriceFromJson(Map json) => + QProductPrice( + (json['priceAmountMicros'] as num).toInt(), + json['priceCurrencyCode'] as String, + json['formattedPrice'] as String, + json['isFree'] as bool, + json['currencySymbol'] as String?, + ); Map _$QProductPriceToJson(QProductPrice instance) => { diff --git a/lib/src/dto/store_product/product_pricing_phase.g.dart b/lib/src/dto/store_product/product_pricing_phase.g.dart index b8708484..f192b646 100644 --- a/lib/src/dto/store_product/product_pricing_phase.g.dart +++ b/lib/src/dto/store_product/product_pricing_phase.g.dart @@ -6,20 +6,20 @@ part of 'product_pricing_phase.dart'; // JsonSerializableGenerator // ************************************************************************** -QProductPricingPhase _$QProductPricingPhaseFromJson(Map json) { - return QProductPricingPhase( - QMapper.requiredProductPriceFromJson(json['price']), - QMapper.requiredSubscriptionPeriodFromJson(json['billingPeriod']), - json['billingCycleCount'] as int, - _$enumDecode(_$QPricingPhaseRecurrenceModeEnumMap, json['recurrenceMode'], - unknownValue: QPricingPhaseRecurrenceMode.unknown), - _$enumDecode(_$QPricingPhaseTypeEnumMap, json['type'], - unknownValue: QPricingPhaseType.unknown), - json['isTrial'] as bool, - json['isIntro'] as bool, - json['isBasePlan'] as bool, - ); -} +QProductPricingPhase _$QProductPricingPhaseFromJson( + Map json) => + QProductPricingPhase( + QMapper.requiredProductPriceFromJson(json['price']), + QMapper.requiredSubscriptionPeriodFromJson(json['billingPeriod']), + (json['billingCycleCount'] as num).toInt(), + $enumDecode(_$QPricingPhaseRecurrenceModeEnumMap, json['recurrenceMode'], + unknownValue: QPricingPhaseRecurrenceMode.unknown), + $enumDecode(_$QPricingPhaseTypeEnumMap, json['type'], + unknownValue: QPricingPhaseType.unknown), + json['isTrial'] as bool, + json['isIntro'] as bool, + json['isBasePlan'] as bool, + ); Map _$QProductPricingPhaseToJson( QProductPricingPhase instance) => @@ -28,39 +28,13 @@ Map _$QProductPricingPhaseToJson( 'billingPeriod': instance.billingPeriod, 'billingCycleCount': instance.billingCycleCount, 'recurrenceMode': - _$QPricingPhaseRecurrenceModeEnumMap[instance.recurrenceMode], - 'type': _$QPricingPhaseTypeEnumMap[instance.type], + _$QPricingPhaseRecurrenceModeEnumMap[instance.recurrenceMode]!, + 'type': _$QPricingPhaseTypeEnumMap[instance.type]!, 'isTrial': instance.isTrial, 'isIntro': instance.isIntro, 'isBasePlan': instance.isBasePlan, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$QPricingPhaseRecurrenceModeEnumMap = { QPricingPhaseRecurrenceMode.infiniteRecurring: 'InfiniteRecurring', QPricingPhaseRecurrenceMode.finiteRecurring: 'FiniteRecurring', diff --git a/lib/src/dto/store_product/product_store_details.g.dart b/lib/src/dto/store_product/product_store_details.g.dart index 873bffe9..694f6cbc 100644 --- a/lib/src/dto/store_product/product_store_details.g.dart +++ b/lib/src/dto/store_product/product_store_details.g.dart @@ -6,30 +6,30 @@ part of 'product_store_details.dart'; // JsonSerializableGenerator // ************************************************************************** -QProductStoreDetails _$QProductStoreDetailsFromJson(Map json) { - return QProductStoreDetails( - json['basePlanId'] as String?, - json['productId'] as String, - json['name'] as String, - json['title'] as String, - json['description'] as String, - QMapper.productOfferDetailsListFromJson(json['subscriptionOfferDetails']), - QMapper.productOfferDetailsFromJson( - json['defaultSubscriptionOfferDetails']), - QMapper.productOfferDetailsFromJson( - json['basePlanSubscriptionOfferDetails']), - QMapper.productInAppDetailsFromJson(json['inAppOfferDetails']), - json['hasTrialOffer'] as bool, - json['hasIntroOffer'] as bool, - json['hasTrialOrIntroOffer'] as bool, - _$enumDecode(_$QProductTypeEnumMap, json['productType'], - unknownValue: QProductType.unknown), - json['isInApp'] as bool, - json['isSubscription'] as bool, - json['isPrepaid'] as bool, - json['isInstallment'] as bool, - ); -} +QProductStoreDetails _$QProductStoreDetailsFromJson( + Map json) => + QProductStoreDetails( + json['basePlanId'] as String?, + json['productId'] as String, + json['name'] as String, + json['title'] as String, + json['description'] as String, + QMapper.productOfferDetailsListFromJson(json['subscriptionOfferDetails']), + QMapper.productOfferDetailsFromJson( + json['defaultSubscriptionOfferDetails']), + QMapper.productOfferDetailsFromJson( + json['basePlanSubscriptionOfferDetails']), + QMapper.productInAppDetailsFromJson(json['inAppOfferDetails']), + json['hasTrialOffer'] as bool, + json['hasIntroOffer'] as bool, + json['hasTrialOrIntroOffer'] as bool, + $enumDecode(_$QProductTypeEnumMap, json['productType'], + unknownValue: QProductType.unknown), + json['isInApp'] as bool, + json['isSubscription'] as bool, + json['isPrepaid'] as bool, + json['isInstallment'] as bool, + ); Map _$QProductStoreDetailsToJson( QProductStoreDetails instance) => @@ -48,39 +48,13 @@ Map _$QProductStoreDetailsToJson( 'hasTrialOffer': instance.hasTrialOffer, 'hasIntroOffer': instance.hasIntroOffer, 'hasTrialOrIntroOffer': instance.hasTrialOrIntroOffer, - 'productType': _$QProductTypeEnumMap[instance.productType], + 'productType': _$QProductTypeEnumMap[instance.productType]!, 'isInApp': instance.isInApp, 'isSubscription': instance.isSubscription, 'isPrepaid': instance.isPrepaid, 'isInstallment': instance.isInstallment, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$QProductTypeEnumMap = { QProductType.trial: 'Trial', QProductType.intro: 'Intro', diff --git a/lib/src/dto/subscription_period.g.dart b/lib/src/dto/subscription_period.g.dart index 3f514b9e..c16372c8 100644 --- a/lib/src/dto/subscription_period.g.dart +++ b/lib/src/dto/subscription_period.g.dart @@ -6,49 +6,22 @@ part of 'subscription_period.dart'; // JsonSerializableGenerator // ************************************************************************** -QSubscriptionPeriod _$QSubscriptionPeriodFromJson(Map json) { - return QSubscriptionPeriod( - json['unitCount'] as int, - _$enumDecode(_$QSubscriptionPeriodUnitEnumMap, json['unit'], - unknownValue: QSubscriptionPeriodUnit.unknown), - json['iso'] as String, - ); -} +QSubscriptionPeriod _$QSubscriptionPeriodFromJson(Map json) => + QSubscriptionPeriod( + (json['unitCount'] as num).toInt(), + $enumDecode(_$QSubscriptionPeriodUnitEnumMap, json['unit'], + unknownValue: QSubscriptionPeriodUnit.unknown), + json['iso'] as String, + ); Map _$QSubscriptionPeriodToJson( QSubscriptionPeriod instance) => { 'unitCount': instance.unitCount, - 'unit': _$QSubscriptionPeriodUnitEnumMap[instance.unit], + 'unit': _$QSubscriptionPeriodUnitEnumMap[instance.unit]!, 'iso': instance.iso, }; -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', - ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} - const _$QSubscriptionPeriodUnitEnumMap = { QSubscriptionPeriodUnit.day: 'Day', QSubscriptionPeriodUnit.week: 'Week', diff --git a/lib/src/dto/transaction.dart b/lib/src/dto/transaction.dart index c2f77f67..6f7e0782 100644 --- a/lib/src/dto/transaction.dart +++ b/lib/src/dto/transaction.dart @@ -21,6 +21,10 @@ class QTransaction { @JsonKey(name: 'offerCode') final String? offerCode; + /// Promotional offer id. + @JsonKey(name: 'promoOfferId') + final String? promoOfferId; + /// Transaction date. @JsonKey( name: 'transactionTimestamp', @@ -68,6 +72,7 @@ class QTransaction { this.originalTransactionId, this.transactionId, this.offerCode, + this.promoOfferId, this.transactionDate, this.expirationDate, this.transactionRevocationDate, diff --git a/lib/src/dto/transaction.g.dart b/lib/src/dto/transaction.g.dart index 4af8218e..6a8f52ba 100644 --- a/lib/src/dto/transaction.g.dart +++ b/lib/src/dto/transaction.g.dart @@ -6,50 +6,23 @@ part of 'transaction.dart'; // JsonSerializableGenerator // ************************************************************************** -QTransaction _$QTransactionFromJson(Map json) { - return QTransaction( - json['originalTransactionId'] as String, - json['transactionId'] as String, - json['offerCode'] as String?, - QMapper.dateTimeFromSecondsTimestamp(json['transactionTimestamp'] as num), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['expirationTimestamp'] as num?), - QMapper.dateTimeFromNullableSecondsTimestamp( - json['transactionRevocationTimestamp'] as num?), - _$enumDecode(_$QTransactionEnvironmentEnumMap, json['environment'], - unknownValue: QTransactionEnvironment.production), - _$enumDecode(_$QTransactionOwnershipTypeEnumMap, json['ownershipType'], - unknownValue: QTransactionOwnershipType.owner), - _$enumDecode(_$QTransactionTypeEnumMap, json['type'], - unknownValue: QTransactionType.unknown), - ); -} - -K _$enumDecode( - Map enumValues, - Object? source, { - K? unknownValue, -}) { - if (source == null) { - throw ArgumentError( - 'A value must be provided. Supported values: ' - '${enumValues.values.join(', ')}', +QTransaction _$QTransactionFromJson(Map json) => QTransaction( + json['originalTransactionId'] as String, + json['transactionId'] as String, + json['offerCode'] as String?, + json['promoOfferId'] as String?, + QMapper.dateTimeFromSecondsTimestamp(json['transactionTimestamp'] as num), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['expirationTimestamp'] as num?), + QMapper.dateTimeFromNullableSecondsTimestamp( + json['transactionRevocationTimestamp'] as num?), + $enumDecode(_$QTransactionEnvironmentEnumMap, json['environment'], + unknownValue: QTransactionEnvironment.production), + $enumDecode(_$QTransactionOwnershipTypeEnumMap, json['ownershipType'], + unknownValue: QTransactionOwnershipType.owner), + $enumDecode(_$QTransactionTypeEnumMap, json['type'], + unknownValue: QTransactionType.unknown), ); - } - - return enumValues.entries.singleWhere( - (e) => e.value == source, - orElse: () { - if (unknownValue == null) { - throw ArgumentError( - '`$source` is not one of the supported values: ' - '${enumValues.values.join(', ')}', - ); - } - return MapEntry(unknownValue, enumValues.values.first); - }, - ).key; -} const _$QTransactionEnvironmentEnumMap = { QTransactionEnvironment.production: 'Production', diff --git a/lib/src/dto/user.g.dart b/lib/src/dto/user.g.dart index 9ac6a143..043cd783 100644 --- a/lib/src/dto/user.g.dart +++ b/lib/src/dto/user.g.dart @@ -6,9 +6,7 @@ part of 'user.dart'; // JsonSerializableGenerator // ************************************************************************** -QUser _$QUserFromJson(Map json) { - return QUser( - json['qonversionId'] as String, - json['identityId'] as String?, - ); -} +QUser _$QUserFromJson(Map json) => QUser( + json['qonversionId'] as String, + json['identityId'] as String?, + ); diff --git a/lib/src/dto/user_properties.g.dart b/lib/src/dto/user_properties.g.dart index b2e5ba25..91a90ad5 100644 --- a/lib/src/dto/user_properties.g.dart +++ b/lib/src/dto/user_properties.g.dart @@ -6,10 +6,9 @@ part of 'user_properties.dart'; // JsonSerializableGenerator // ************************************************************************** -QUserProperties _$QUserPropertiesFromJson(Map json) { - return QUserProperties( - (json['properties'] as List) - .map((e) => QUserProperty.fromJson(e as Map)) - .toList(), - ); -} +QUserProperties _$QUserPropertiesFromJson(Map json) => + QUserProperties( + (json['properties'] as List) + .map((e) => QUserProperty.fromJson(e as Map)) + .toList(), + ); diff --git a/lib/src/dto/user_property.g.dart b/lib/src/dto/user_property.g.dart index e2ca1b08..fbabb50e 100644 --- a/lib/src/dto/user_property.g.dart +++ b/lib/src/dto/user_property.g.dart @@ -6,9 +6,8 @@ part of 'user_property.dart'; // JsonSerializableGenerator // ************************************************************************** -QUserProperty _$QUserPropertyFromJson(Map json) { - return QUserProperty( - json['key'] as String, - json['value'] as String, - ); -} +QUserProperty _$QUserPropertyFromJson(Map json) => + QUserProperty( + json['key'] as String, + json['value'] as String, + ); diff --git a/lib/src/internal/constants.dart b/lib/src/internal/constants.dart index 09957758..9669ceb8 100644 --- a/lib/src/internal/constants.dart +++ b/lib/src/internal/constants.dart @@ -34,12 +34,15 @@ class Constants { static const kPurchaseContextKeys = 'contextKeys'; static const kPurchaseQuantity = 'quantity'; static const kIncludeEmptyContextKey = 'includeEmptyContextKey'; + static const kDiscountId = 'discountId'; + static const kPromoOffer = 'promoOffer'; // MethodChannel methods names static const mInitialize = 'initialize'; static const mSyncHistoricalData = 'syncHistoricalData'; static const mSyncStoreKit2Purchases = 'syncStoreKit2Purchases'; static const mProducts = 'products'; + static const mGetPromotionalOffer = 'getPromotionalOffer'; static const mPurchase = 'purchase'; static const mPromoPurchase = 'promoPurchase'; static const mUpdatePurchase = 'updatePurchase'; diff --git a/lib/src/internal/mapper.dart b/lib/src/internal/mapper.dart index d04506c3..4e08312c 100644 --- a/lib/src/internal/mapper.dart +++ b/lib/src/internal/mapper.dart @@ -9,13 +9,15 @@ import '../dto/store_product/product_store_details.dart'; import '../dto/transaction.dart'; import '../dto/entitlement_grant_type.dart'; -import '../dto/sk_product/discount.dart'; -import '../dto/sk_product/sk_product_wrapper.dart'; +import '../dto/sk_product/sk_product_discount.dart'; +import '../dto/sk_product/sk_product.dart'; +import '../dto/sk_product/sk_payment_discount.dart'; import '../dto/sk_product/subscription_period.dart'; import '../dto/sku_details/sku_details.dart'; import '../dto/product.dart'; import '../dto/entitlement.dart'; import '../dto/offerings.dart'; +import '../dto/promotional_offer.dart'; import '../dto/subscription_period.dart'; import '../dto/user.dart'; import '../dto/remote_config.dart'; @@ -80,6 +82,14 @@ class QMapper { return QRemoteConfigList.fromJson(remoteConfigListMap); } + static QPromotionalOffer? promotionalOfferFromJson(String? jsonString) { + if (jsonString == null) return null; + + final promoOfferMap = Map.from(jsonDecode(jsonString)); + + return QPromotionalOffer.fromJson(promoOfferMap); + } + static Map eligibilityFromJson(String? jsonString) { if (jsonString == null) return {}; @@ -142,42 +152,56 @@ class QMapper { return QUserProperties.fromJson(propertiesMap); } - static SKProductWrapper? skProductFromJson(dynamic json) { + static SKProduct? skProductFromJson(dynamic json) { if (json == null) return null; final map = Map.from(json); try { - return SKProductWrapper.fromJson(map); + return SKProduct.fromJson(map); } catch (e) { print('Could not parse SKProduct: $e'); return null; } } - static SKPriceLocaleWrapper? skPriceLocaleFromJson(dynamic json) { + static SKPriceLocale? skPriceLocaleFromJson(dynamic json) { if (json == null) return null; final map = Map.from(json); - return SKPriceLocaleWrapper.fromJson(map); + return SKPriceLocale.fromJson(map); } - static SKProductSubscriptionPeriodWrapper? + static SKProductSubscriptionPeriod? skProductSubscriptionPeriodFromJson(dynamic json) { if (json == null) return null; final map = Map.from(json); - return SKProductSubscriptionPeriodWrapper.fromJson(map); + return SKProductSubscriptionPeriod.fromJson(map); } - static SKProductDiscountWrapper? skProductDiscountFromJson(dynamic json) { + static SKProductDiscount? skProductDiscountFromJson(dynamic json) { if (json == null) return null; + return requiredSkProductDiscountFromJson(json); + } + + static SKProductDiscount requiredSkProductDiscountFromJson(dynamic json) { + if (json == null) throw Exception('Could not parse SKProductDiscount as json is null'); + final map = Map.from(json); - return SKProductDiscountWrapper.fromJson(map); + return SKProductDiscount.fromJson(map); + } + + static SKPaymentDiscount skPaymentDiscountFromJson(dynamic json) { + if (json == null) throw Exception('Could not parse SkPaymentDiscount as json is null'); + + final map = Map.from(json); + + return SKPaymentDiscount.fromJson(map); } // ignore: deprecated_member_use_from_same_package @@ -210,6 +234,12 @@ class QMapper { .toList(); } + static List? skProductDiscountsFromList(List? json) { + if (json == null) return null; + return json.map((e) => SKProductDiscount.fromJson(e as Map)) + .toList(); + } + static QProductStoreDetails? storeProductDetailsFromJson(dynamic json) { if (json == null) return null; diff --git a/lib/src/internal/qonversion_internal.dart b/lib/src/internal/qonversion_internal.dart index 93d4e909..d6716236 100644 --- a/lib/src/internal/qonversion_internal.dart +++ b/lib/src/internal/qonversion_internal.dart @@ -62,6 +62,23 @@ class QonversionInternal implements Qonversion { } } + @override + Future getPromotionalOffer(QProduct product, SKProductDiscount discount) async { + if (Platform.isAndroid) { + return null; + } + + final promotionalOfferJson = await _channel.invokeMethod( + Constants.mGetPromotionalOffer, { + Constants.kProductId: product.qonversionId, + Constants.kDiscountId: discount.identifier, + } + ); + + final result = QMapper.promotionalOfferFromJson(promotionalOfferJson); + return result; + } + @override Future> purchase(QPurchaseModel purchaseModel) async { try { @@ -86,6 +103,15 @@ class QonversionInternal implements Qonversion { purchaseOptions = new QPurchaseOptionsBuilder().build(); } + final Map promoOfferData = new Map(); + if (purchaseOptions.promotionalOffer != null) { + promoOfferData['productDiscountId'] = purchaseOptions.promotionalOffer?.productDiscount.identifier; + promoOfferData['keyIdentifier'] = purchaseOptions.promotionalOffer?.paymentDiscount.keyIdentifier; + promoOfferData['nonce'] = purchaseOptions.promotionalOffer?.paymentDiscount.nonce; + promoOfferData['signature'] = purchaseOptions.promotionalOffer?.paymentDiscount.signature; + promoOfferData['timestamp'] = purchaseOptions.promotionalOffer?.paymentDiscount.timestamp; + } + final rawResult = await _channel .invokeMethod(Constants.mPurchase, { Constants.kProductId: product.qonversionId, @@ -95,6 +121,7 @@ class QonversionInternal implements Qonversion { Constants.kUpdatePolicyKey: purchaseOptions.updatePolicy, Constants.kPurchaseContextKeys: purchaseOptions.contextKeys, Constants.kPurchaseQuantity: purchaseOptions.quantity, + Constants.kPromoOffer: promoOfferData, }); final result = QMapper.entitlementsFromJson(rawResult); diff --git a/lib/src/qonversion.dart b/lib/src/qonversion.dart index 22fdfd00..dadc86c0 100644 --- a/lib/src/qonversion.dart +++ b/lib/src/qonversion.dart @@ -51,6 +51,8 @@ abstract class Qonversion { /// Call this function to sync purchases if you are using StoreKit2 and our SDK in Analytics mode. Future syncStoreKit2Purchases(); + Future getPromotionalOffer(QProduct product, SKProductDiscount discount); + /// Make a purchase and validate it through server-to-server using Qonversion's Backend. /// [purchaseModel] necessary information for purchase. /// diff --git a/macos/Classes/SwiftQonversionPlugin.swift b/macos/Classes/SwiftQonversionPlugin.swift index 8e3cbb22..7ac4b2f8 100644 --- a/macos/Classes/SwiftQonversionPlugin.swift +++ b/macos/Classes/SwiftQonversionPlugin.swift @@ -89,8 +89,11 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { case "initialize": return initialize(args, result) + case "getPromotionalOffer": + return getPromotionalOffer(args, result) + case "purchase": - return purchase(args["productId"] as? String, quantity: args["quantity"] as? Int, contextKeys: args["contextKeys"] as? [String], result) + return purchase(args, result) case "remoteConfig": return remoteConfig(args["contextKey"] as? String, result) @@ -162,19 +165,31 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { qonversionSandwich?.identify(userId, getDefaultCompletion(result)) } + private func getPromotionalOffer(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let productId = args["productId"] as? String else { + return result(FlutterError.noNecessaryData) + } + guard let discountId = args["discountId"] as? String else { + return result(FlutterError.noNecessaryData) + } + + qonversionSandwich?.getPromotionalOffer(productId, productDiscountId:discountId, completion:getDefaultCompletion(result)) + } + private func products(_ result: @escaping FlutterResult) { qonversionSandwich?.products(getDefaultCompletion(result)) } - - private func purchase(_ productId: String?, quantity: Int?, contextKeys: [String]?, _ result: @escaping FlutterResult) { - guard let productId = productId else { + + private func purchase(_ args: [String: Any], _ result: @escaping FlutterResult) { + guard let productId = args["productId"] as? String else { return result(FlutterError.noNecessaryData) } - - let contextKeys = contextKeys ?? [] - let quantity = quantity ?? 1 - - qonversionSandwich?.purchase(productId, quantity:quantity, contextKeys:contextKeys, completion: getJsonCompletion(result)) + + let contextKeys = args["contextKeys"] as? [String] ?? [] + let quantity = args["quantity"] as? Int ?? 1 + let promoOfferData = args["promoOffer"] as? [String: Any] ?? [:] + + qonversionSandwich?.purchase(productId, quantity:quantity, contextKeys:contextKeys, promoOffer:promoOfferData, completion:getJsonCompletion(result)) } private func checkEntitlements(_ result: @escaping FlutterResult) { diff --git a/macos/qonversion_flutter.podspec b/macos/qonversion_flutter.podspec index d1898f3d..876bc788 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", "5.1.7" + s.dependency "QonversionSandwich", "5.2.0" s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' diff --git a/pubspec.lock b/pubspec.lock index 39e2fdcc..34275057 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,31 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: d93b0378aadce9c1388108067946276582c2ae89426c64c17920c74988508fed + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "22.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "581a0281129283e75d4d67d6ac6e391c0515cdce37eb6eb4bc8a52e65d2b16b6" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "1.7.2" + version: "6.7.0" args: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" async: dependency: transitive description: @@ -45,50 +50,50 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - sha256: ad77deb6e9c143a3f550fbb4c5c1e0c6aadabe24274898d06b9526c61b9cf4fb + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "4.0.2" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: a171129ff393d360a5ec9ba3a2277e0d7e713027709f08196e8192688b537074 + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "361d73f37cd48c47a81a61421eb1cc4cfd2324516fbb52f1bc4c9a01834ef2de" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.1.11" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "0db1b64c84fa803603fa406f8721959036e898cc9575d6ce4a3067581b9276c0" + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "7.3.2" built_collection: dependency: transitive description: @@ -117,18 +122,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - cli_util: - dependency: transitive - description: - name: cli_util - sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "2.0.3" clock: dependency: transitive description: @@ -141,10 +138,10 @@ packages: dependency: transitive description: name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.10.1" collection: dependency: "direct main" description: @@ -157,26 +154,26 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" dart_style: dependency: transitive description: name: dart_style - sha256: "7f5b48e6a448c4b46250a6113857a00eaa82821ef5a3d7f42e68eb69d1283fa3" + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.3.7" fake_async: dependency: transitive description: @@ -189,18 +186,18 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -215,10 +212,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "4f4a162323c86ffc1245765cfe138872b8f069deb42f7dbb36115fa27f31469b" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "4.0.0" glob: dependency: transitive description: @@ -263,26 +260,26 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.1" json_annotation: dependency: "direct main" description: name: json_annotation - sha256: "0aa7409f6c82acfab96853b8b0c7503de49918cbe705a57cfdeb477756b4521b" + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.9.0" json_serializable: dependency: "direct dev" description: name: json_serializable - sha256: "86d3edf6914d6562ed4c7d9288239fbf1a9ee3c498ed0089a535c0d3703bb323" + sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "6.9.0" leak_tracker: dependency: transitive description: @@ -311,10 +308,18 @@ packages: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -343,10 +348,10 @@ packages: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" package_config: dependency: transitive description: @@ -363,14 +368,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" pool: dependency: transitive description: @@ -391,10 +388,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: "0e01f805457ef610ccaf8d18067596afc34107a27149778b06b2083edbc140c1" + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.3.0" shelf: dependency: transitive description: @@ -407,10 +404,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -420,10 +417,18 @@ packages: dependency: transitive description: name: source_gen - sha256: ffb7124eb6752de71e87a122cc50a8a191044add69fd990d76958bc38ee552fd + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.3.4" source_span: dependency: transitive description: @@ -484,18 +489,18 @@ packages: dependency: transitive description: name: timing - sha256: c386d07d7f5efc613479a7c4d9d64b03710b03cfaa7e8ad5f2bfb295a1f0dfad + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" vector_math: dependency: transitive description: @@ -524,18 +529,26 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.0" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + url: "https://pub.dev" + source: hosted + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "3.0.1" yaml: dependency: transitive description: @@ -545,5 +558,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.4.0 <4.0.0" + dart: ">=3.5.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index f34160b5..f9a71d0b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,8 +17,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.0.6 - json_serializable: ^4.1.0 + build_runner: ^2.4.13 + json_serializable: ^6.9.0 flutter: plugin: From 51276317ae3c9cc6137ed5d68083e347779c1b5b Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Fri, 22 Nov 2024 14:56:41 +0300 Subject: [PATCH 2/9] CR fixes --- ios/Classes/SwiftQonversionPlugin.swift | 6 ++---- lib/src/qonversion.dart | 7 +++++++ macos/Classes/SwiftQonversionPlugin.swift | 6 ++---- pubspec.yaml | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ios/Classes/SwiftQonversionPlugin.swift b/ios/Classes/SwiftQonversionPlugin.swift index 8b517664..64717aa0 100644 --- a/ios/Classes/SwiftQonversionPlugin.swift +++ b/ios/Classes/SwiftQonversionPlugin.swift @@ -208,10 +208,8 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { } private func getPromotionalOffer(_ args: [String: Any], _ result: @escaping FlutterResult) { - guard let productId = args["productId"] as? String else { - return result(FlutterError.noNecessaryData) - } - guard let discountId = args["discountId"] as? String else { + guard let productId = args["productId"] as? String, + let discountId = args["discountId"] as? String else { return result(FlutterError.noNecessaryData) } diff --git a/lib/src/qonversion.dart b/lib/src/qonversion.dart index dadc86c0..4a1135ee 100644 --- a/lib/src/qonversion.dart +++ b/lib/src/qonversion.dart @@ -51,6 +51,13 @@ abstract class Qonversion { /// Call this function to sync purchases if you are using StoreKit2 and our SDK in Analytics mode. Future syncStoreKit2Purchases(); + /// iOS only. + /// Retrieve the promotional offer for the [product] and the product [discount] if it exists. + /// Make sure to call this function before displaying product details to the user. + /// The generated signature for the promotional offer is valid for a single transaction. + /// If the purchase fails, you need to call this function again to obtain a new promotional offer signature. + /// Use this signature to complete the purchase through the purchase function, along with the purchase options object. + /// Returns the promise with the [QPromotionalOffer]. Future getPromotionalOffer(QProduct product, SKProductDiscount discount); /// Make a purchase and validate it through server-to-server using Qonversion's Backend. diff --git a/macos/Classes/SwiftQonversionPlugin.swift b/macos/Classes/SwiftQonversionPlugin.swift index 7ac4b2f8..39eccab1 100644 --- a/macos/Classes/SwiftQonversionPlugin.swift +++ b/macos/Classes/SwiftQonversionPlugin.swift @@ -166,10 +166,8 @@ public class SwiftQonversionPlugin: NSObject, FlutterPlugin { } private func getPromotionalOffer(_ args: [String: Any], _ result: @escaping FlutterResult) { - guard let productId = args["productId"] as? String else { - return result(FlutterError.noNecessaryData) - } - guard let discountId = args["discountId"] as? String else { + guard let productId = args["productId"] as? String, + let discountId = args["discountId"] as? String else { return result(FlutterError.noNecessaryData) } diff --git a/pubspec.yaml b/pubspec.yaml index f9a71d0b..fabdb64a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.4.13 - json_serializable: ^6.9.0 + json_serializable: ^6.8.0 flutter: plugin: From 5c609c1c4de131aa6914345e8aef94ab09d3e4af Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 11:44:17 +0300 Subject: [PATCH 3/9] CR fixes --- pubspec.lock | 71 ++++++++++++++++++---------------------------------- pubspec.yaml | 5 ++-- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 34275057..fedc4779 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a url: "https://pub.dev" source: hosted - version: "72.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.2" + version: "61.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "5.13.0" args: dependency: transitive description: @@ -87,7 +82,7 @@ packages: source: hosted version: "2.4.13" build_runner_core: - dependency: transitive + dependency: "direct dev" description: name: build_runner_core sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 @@ -122,10 +117,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.0.1" clock: dependency: transitive description: @@ -170,10 +165,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" url: "https://pub.dev" source: hosted - version: "2.3.7" + version: "2.3.2" fake_async: dependency: transitive description: @@ -260,10 +255,10 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.6.7" json_annotation: dependency: "direct main" description: @@ -276,10 +271,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c + sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b url: "https://pub.dev" source: hosted - version: "6.9.0" + version: "6.8.0" leak_tracker: dependency: transitive description: @@ -312,14 +307,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" - macros: - dependency: transitive - description: - name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" - url: "https://pub.dev" - source: hosted - version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -348,10 +335,10 @@ packages: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.6" package_config: dependency: transitive description: @@ -388,10 +375,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + sha256: "0e01f805457ef610ccaf8d18067596afc34107a27149778b06b2083edbc140c1" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.1.0" shelf: dependency: transitive description: @@ -404,10 +391,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -489,10 +476,10 @@ packages: dependency: transitive description: name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + sha256: c386d07d7f5efc613479a7c4d9d64b03710b03cfaa7e8ad5f2bfb295a1f0dfad url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.0" typed_data: dependency: transitive description: @@ -529,26 +516,18 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.1.0" - web_socket: - dependency: transitive - description: - name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" - url: "https://pub.dev" - source: hosted - version: "0.1.6" + version: "0.5.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "2.4.5" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index fabdb64a..f69dffd3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,8 +17,9 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.4.13 - json_serializable: ^6.8.0 + build_runner: ^2.4.6 + json_serializable: ^6.6.2 + build_runner_core: ^7.2.9 flutter: plugin: From bb6a6f70ae32ee1400a2dc2fa138c736d17f7db2 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 11:47:58 +0300 Subject: [PATCH 4/9] CR fixes --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f69dffd3..a8cd089b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - build_runner: ^2.4.6 + build_runner: ^2.3.3 json_serializable: ^6.6.2 build_runner_core: ^7.2.9 From 370f9a93b11f5a8583c74ecb41486064233452ed Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 11:54:12 +0300 Subject: [PATCH 5/9] CR fixes --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a8cd089b..00907590 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,7 +19,7 @@ dev_dependencies: sdk: flutter build_runner: ^2.3.3 json_serializable: ^6.6.2 - build_runner_core: ^7.2.9 + build_runner_core: ^7.2.7+1 flutter: plugin: From bb2dc8d10b7c71c2ee476349cdbe5d190688205f Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 13:47:37 +0300 Subject: [PATCH 6/9] Minimal dart version upgraded to 2.14 --- example/pubspec.yaml | 2 +- lib/src/dto/sku_details/sku_details.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index a2deae72..51f7b2fb 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: 'none' version: 1.0.0 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.14.0 <3.0.0" flutter: ">=1.12.13+hotfix.6" dependencies: diff --git a/lib/src/dto/sku_details/sku_details.dart b/lib/src/dto/sku_details/sku_details.dart index c3ec6281..08edf1cb 100644 --- a/lib/src/dto/sku_details/sku_details.dart +++ b/lib/src/dto/sku_details/sku_details.dart @@ -108,7 +108,7 @@ class SkuDetailsWrapper { Map toJson() => _$SkuDetailsWrapperToJson(this); @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (other.runtimeType != runtimeType) { return false; } diff --git a/pubspec.yaml b/pubspec.yaml index 00907590..fedf7673 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ homepage: 'https://qonversion.io' repository: 'https://github.com/qonversion/flutter-sdk' environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.14.0 <3.0.0' flutter: ">=1.10.0" dependencies: From 5be0dc02559b71031b98de38cbfa838ecab6b401 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 13:54:50 +0300 Subject: [PATCH 7/9] Fixed warnings --- lib/src/dto/product.dart | 10 +++++----- lib/src/dto/sku_details/sku_details.g.dart | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/src/dto/product.dart b/lib/src/dto/product.dart index 0c0af940..d05caf46 100644 --- a/lib/src/dto/product.dart +++ b/lib/src/dto/product.dart @@ -83,23 +83,23 @@ class QProduct { final String? prettyPrice; /// Localized price of the product - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) double? price; /// Store Product currency code, such as USD - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) String? currencyCode; /// Store product title - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) String? storeTitle; /// Store product description - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) String? storeDescription; /// Formatted introductory price of the subscription, including its currency sign, such as €2.99 - @JsonKey(ignore: true) + @JsonKey(includeFromJson: false, includeToJson: false) String? prettyIntroductoryPrice; QProduct( diff --git a/lib/src/dto/sku_details/sku_details.g.dart b/lib/src/dto/sku_details/sku_details.g.dart index b4d728fc..cd67027b 100644 --- a/lib/src/dto/sku_details/sku_details.g.dart +++ b/lib/src/dto/sku_details/sku_details.g.dart @@ -6,7 +6,9 @@ part of 'sku_details.dart'; // JsonSerializableGenerator // ************************************************************************** +// ignore: deprecated_member_use_from_same_package SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) => + // ignore: deprecated_member_use_from_same_package SkuDetailsWrapper( description: json['description'] as String, freeTrialPeriod: json['freeTrialPeriod'] as String, @@ -28,6 +30,7 @@ SkuDetailsWrapper _$SkuDetailsWrapperFromJson(Map json) => originalJson: json['originalJson'] as String, ); +// ignore: deprecated_member_use_from_same_package Map _$SkuDetailsWrapperToJson(SkuDetailsWrapper instance) => { 'description': instance.description, From c0885842965337549fc75103dad4c5d6ab5bdf01 Mon Sep 17 00:00:00 2001 From: SpertsyanKM Date: Mon, 25 Nov 2024 11:01:39 +0000 Subject: [PATCH 8/9] [create-pull-request] automated change --- CHANGELOG.md | 3 +++ lib/src/internal/qonversion_internal.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93511a1b..94ad426b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 9.2.0 +* // Update changelog here + ## 9.1.5 * Attempt to fix crash and race conditions in the User Properties manager. * Fixed popover presentation style for iPad diff --git a/lib/src/internal/qonversion_internal.dart b/lib/src/internal/qonversion_internal.dart index d6716236..3c8e75a7 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 = "9.1.5"; + static const String _sdkVersion = "9.2.0"; final MethodChannel _channel = MethodChannel('qonversion_plugin'); diff --git a/pubspec.yaml b/pubspec.yaml index fedf7673..638b8c8b 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: 9.1.5 +version: 9.2.0 homepage: 'https://qonversion.io' repository: 'https://github.com/qonversion/flutter-sdk' From 040e348a743add3ddc61290e865841f31eb6f70e Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 25 Nov 2024 14:06:04 +0300 Subject: [PATCH 9/9] Update CHANGELOG.md --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94ad426b..14972960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 9.2.0 -* // Update changelog here +* iOS promotional offers supported. For the details see the [documentation](https://documentation.qonversion.io/docs/apple-promotional-offers). +* Minimal supported Dart SDK version is bumped to 2.14.0. ## 9.1.5 * Attempt to fix crash and race conditions in the User Properties manager. @@ -21,8 +22,8 @@ * iOS error codes improved ## 9.1.0 -* Added option to set context keys, quantity and other options for purchases. Context keys will allow you to associate the purchase with remote configuration if the product info was loaded from there. -* Deprecated old purchase functions. Use new one instead. +* Added option to set context keys, quantity, and other options for purchases. Context keys will allow you to associate the purchase with remote configuration if the product info was loaded from there. +* Deprecated old purchase functions. Use the new one instead. ## 9.0.2 * Fixed bug with `checkEntitlements` calls on Android when the callback might not have been called after subscription state changes during the app session.