parseProductFromNative function
Implementation
gentype.ProductCommon parseProductFromNative(
Map<String, dynamic> json,
String type, {
required bool fallbackIsIOS,
}) {
// Determine platform from JSON data if available, otherwise use heuristics, then runtime
gentype.IapPlatform platform;
final dynamic platformRaw = json['platform'];
if (platformRaw is String) {
final v = platformRaw.toLowerCase();
platform = (v == 'android')
? gentype.IapPlatform.Android
: gentype.IapPlatform.IOS;
} else if (platformRaw is gentype.IapPlatform) {
platform = platformRaw;
} else {
// Heuristics based on well-known platform-specific fields
final looksAndroid =
json.containsKey('oneTimePurchaseOfferDetailsAndroid') ||
json.containsKey('subscriptionOfferDetailsAndroid') ||
json.containsKey('nameAndroid');
final looksIOS = json.containsKey('subscriptionGroupIdIOS') ||
json.containsKey('jsonRepresentationIOS') ||
json.containsKey('environmentIOS');
if (looksAndroid && !looksIOS) {
platform = gentype.IapPlatform.Android;
} else if (looksIOS && !looksAndroid) {
platform = gentype.IapPlatform.IOS;
} else {
platform =
fallbackIsIOS ? gentype.IapPlatform.IOS : gentype.IapPlatform.Android;
}
}
double? parsePrice(dynamic value) {
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value);
return null;
}
final productId = (json['id']?.toString() ??
json['productId']?.toString() ??
json['sku']?.toString() ??
json['productIdentifier']?.toString() ??
'')
.trim();
final title = json['title']?.toString() ?? productId;
final description = json['description']?.toString() ?? '';
final currency = json['currency']?.toString() ?? '';
final displayPrice = json['displayPrice']?.toString() ??
json['localizedPrice']?.toString() ??
'0';
final priceValue = parsePrice(json['price']);
final productType = _parseProductType(type);
if (productType == gentype.ProductType.Subs) {
if (platform == gentype.IapPlatform.IOS) {
return gentype.ProductSubscriptionIOS(
currency: currency,
description: description,
displayNameIOS: json['displayNameIOS']?.toString() ?? title,
displayPrice: displayPrice,
id: productId,
isFamilyShareableIOS: json['isFamilyShareableIOS'] as bool? ?? false,
jsonRepresentationIOS:
json['jsonRepresentationIOS']?.toString() ?? '{}',
platform: platform,
title: title,
type: productType,
typeIOS: _parseProductTypeIOS(json['typeIOS']?.toString()),
debugDescription: json['debugDescription']?.toString(),
discountsIOS:
_parseDiscountsIOS(json['discountsIOS'] ?? json['discounts']),
displayName: json['displayName']?.toString(),
introductoryPriceAsAmountIOS:
json['introductoryPriceAsAmountIOS']?.toString(),
introductoryPriceIOS: json['introductoryPriceIOS']?.toString(),
introductoryPriceNumberOfPeriodsIOS:
json['introductoryPriceNumberOfPeriodsIOS']?.toString(),
introductoryPricePaymentModeIOS:
_parsePaymentMode(json['introductoryPricePaymentModeIOS']),
introductoryPriceSubscriptionPeriodIOS: _parseSubscriptionPeriod(
json['introductoryPriceSubscriptionPeriodIOS'],
),
price: priceValue,
subscriptionInfoIOS: _parseSubscriptionInfoIOS(
json['subscriptionInfoIOS'] ?? json['subscription'],
),
subscriptionPeriodNumberIOS:
json['subscriptionPeriodNumberIOS']?.toString(),
subscriptionPeriodUnitIOS:
_parseSubscriptionPeriod(json['subscriptionPeriodUnitIOS']),
);
}
final subscriptionOffers = _parseOfferDetails(
json['subscriptionOfferDetailsAndroid'],
);
return gentype.ProductSubscriptionAndroid(
currency: currency,
description: description,
displayPrice: displayPrice,
id: productId,
nameAndroid: json['nameAndroid']?.toString() ?? productId,
platform: platform,
subscriptionOfferDetailsAndroid: subscriptionOffers,
title: title,
type: productType,
debugDescription: json['debugDescription']?.toString(),
displayName: json['displayName']?.toString(),
oneTimePurchaseOfferDetailsAndroid: _parseOneTimePurchaseOfferDetail(
json['oneTimePurchaseOfferDetailsAndroid'],
),
price: priceValue,
);
}
if (platform == gentype.IapPlatform.IOS) {
return gentype.ProductIOS(
currency: currency,
description: description,
displayNameIOS: json['displayNameIOS']?.toString() ?? title,
displayPrice: displayPrice,
id: productId,
isFamilyShareableIOS: json['isFamilyShareableIOS'] as bool? ?? false,
jsonRepresentationIOS: json['jsonRepresentationIOS']?.toString() ?? '{}',
platform: platform,
title: title,
type: productType,
typeIOS: _parseProductTypeIOS(json['typeIOS']?.toString()),
debugDescription: json['debugDescription']?.toString(),
displayName: json['displayName']?.toString(),
price: priceValue,
subscriptionInfoIOS: _parseSubscriptionInfoIOS(
json['subscriptionInfoIOS'] ?? json['subscription'],
),
);
}
final androidOffers = _parseOfferDetails(
json['subscriptionOfferDetailsAndroid'],
);
return gentype.ProductAndroid(
currency: currency,
description: description,
displayPrice: displayPrice,
id: productId,
nameAndroid: json['nameAndroid']?.toString() ?? productId,
platform: platform,
title: title,
type: productType,
debugDescription: json['debugDescription']?.toString(),
displayName: json['displayName']?.toString(),
oneTimePurchaseOfferDetailsAndroid: _parseOneTimePurchaseOfferDetail(
json['oneTimePurchaseOfferDetailsAndroid'],
),
price: priceValue,
subscriptionOfferDetailsAndroid:
androidOffers.isEmpty ? null : androidOffers,
);
}