Skip to content

Commit

Permalink
Paywalls: new {{ sub_relative_discount }} variable (#3131)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Sep 15, 2023
1 parent 023b59b commit f617fbb
Show file tree
Hide file tree
Showing 51 changed files with 208 additions and 63 deletions.
17 changes: 10 additions & 7 deletions RevenueCatUI/Data/ProcessedLocalizedConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,24 @@ struct ProcessedLocalizedConfiguration: PaywallLocalizedConfiguration {
init(
_ configuration: PaywallData.LocalizedConfiguration,
_ dataProvider: VariableDataProvider,
_ context: VariableHandler.Context,
_ locale: Locale
) {
self.init(
title: configuration.title.processed(with: dataProvider, locale: locale),
subtitle: configuration.subtitle?.processed(with: dataProvider, locale: locale),
callToAction: configuration.callToAction.processed(with: dataProvider, locale: locale),
title: configuration.title.processed(with: dataProvider, context: context, locale: locale),
subtitle: configuration.subtitle?.processed(with: dataProvider, context: context, locale: locale),
callToAction: configuration.callToAction.processed(with: dataProvider, context: context, locale: locale),
callToActionWithIntroOffer: configuration.callToActionWithIntroOffer?.processed(with: dataProvider,
context: context,
locale: locale),
offerDetails: configuration.offerDetails?.processed(with: dataProvider, locale: locale),
offerDetails: configuration.offerDetails?.processed(with: dataProvider, context: context, locale: locale),
offerDetailsWithIntroOffer: configuration.offerDetailsWithIntroOffer?.processed(with: dataProvider,
context: context,
locale: locale),
offerName: configuration.offerName?.processed(with: dataProvider, locale: locale),
offerName: configuration.offerName?.processed(with: dataProvider, context: context, locale: locale),
features: configuration.features.map {
.init(title: $0.title.processed(with: dataProvider, locale: locale),
content: $0.content?.processed(with: dataProvider, locale: locale),
.init(title: $0.title.processed(with: dataProvider, context: context, locale: locale),
content: $0.content?.processed(with: dataProvider, context: context, locale: locale),
iconID: $0.iconID)
}
)
Expand Down
20 changes: 13 additions & 7 deletions RevenueCatUI/Data/TemplateViewConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,24 @@ extension TemplateViewConfiguration.PackageConfiguration {
let filtered = TemplateViewConfiguration.filter(packages: packages, with: filter)
let mostExpensivePricePerMonth = Self.mostExpensivePricePerMonth(in: filtered)

let filteredPackages = filtered
let filteredPackages: [TemplateViewConfiguration.Package] = filtered
.map { package in
TemplateViewConfiguration.Package(
let discount = Self.discount(
from: package.storeProduct.pricePerMonth?.doubleValue,
relativeTo: mostExpensivePricePerMonth
)

return .init(
content: package,
localization: localization.processVariables(with: package, locale: locale),
localization: localization.processVariables(
with: package,
context: .init(discountRelativeToMostExpensivePerMonth: discount),
locale: locale
),
currentlySubscribed: activelySubscribedProductIdentifiers.contains(
package.storeProduct.productIdentifier
),
discountRelativeToMostExpensivePerMonth: Self.discount(
from: package.storeProduct.pricePerMonth?.doubleValue,
relativeTo: mostExpensivePricePerMonth
)
discountRelativeToMostExpensivePerMonth: discount
)
}

Expand Down
79 changes: 58 additions & 21 deletions RevenueCatUI/Data/Variables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ import RevenueCat
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
extension PaywallData.LocalizedConfiguration {

func processVariables(with package: Package, locale: Locale = .current) -> ProcessedLocalizedConfiguration {
return .init(self, package, locale)
func processVariables(
with package: Package,
context: VariableHandler.Context,
locale: Locale = .current
) -> ProcessedLocalizedConfiguration {
return .init(self, package, context, locale)
}

}
Expand All @@ -38,22 +42,37 @@ protocol VariableDataProvider {

func localizedPricePerPeriod(_ locale: Locale) -> String
func localizedPriceAndPerMonth(_ locale: Locale) -> String
func localizedRelativeDiscount(_ discount: Double?, _ locale: Locale) -> String?

}

/// Processes strings, replacing `{{ variable }}` with their associated content.
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
enum VariableHandler {

/// Information necessary for computing variables
struct Context {

var discountRelativeToMostExpensivePerMonth: Double?

}

static func processVariables(
in string: String,
with provider: VariableDataProvider,
context: Context,
locale: Locale = .current
) -> String {
if #available(iOS 16.0, macOS 13.0, tvOS 16.0, *) {
return VariableHandlerIOS16.processVariables(in: string, with: provider, locale: locale)
return VariableHandlerIOS16.processVariables(in: string,
with: provider,
context: context,
locale: locale)
} else {
return VariableHandlerIOS15.processVariables(in: string, with: provider, locale: locale)
return VariableHandlerIOS15.processVariables(in: string,
with: provider,
context: context,
locale: locale)
}
}

Expand All @@ -65,21 +84,25 @@ enum VariableHandler {
)
}

fileprivate typealias ValueProvider = (VariableDataProvider, Locale) -> String?
fileprivate typealias ValueProvider = (VariableDataProvider,
VariableHandler.Context,
Locale) -> String?

// swiftlint:disable:next cyclomatic_complexity
fileprivate static func provider(for variableName: String) -> ValueProvider? {
switch variableName {
case "app_name": return { (provider, _) in provider.applicationName }
case "price": return { (provider, _) in provider.localizedPrice }
case "price_per_period": return { $0.localizedPricePerPeriod($1) }
case "total_price_and_per_month": return { $0.localizedPriceAndPerMonth($1) }
case "product_name": return { (provider, _) in provider.productName }
case "sub_period": return { $0.periodName($1) }
case "sub_price_per_month": return { (provider, _) in provider.localizedPricePerMonth }
case "sub_duration": return { $0.subscriptionDuration($1) }
case "sub_offer_duration": return { $0.introductoryOfferDuration($1) }
case "sub_offer_price": return { (provider, _) in provider.localizedIntroductoryOfferPrice }
case "app_name": return { (provider, _, _) in provider.applicationName }
case "price": return { (provider, _, _) in provider.localizedPrice }
case "price_per_period": return { (provider, _, locale) in provider.localizedPricePerPeriod(locale) }
case "total_price_and_per_month": return { (provider, _, locale) in provider.localizedPriceAndPerMonth(locale) }
case "product_name": return { (provider, _, _) in provider.productName }
case "sub_period": return { (provider, _, locale) in provider.periodName(locale) }
case "sub_price_per_month": return { (provider, _, _) in provider.localizedPricePerMonth }
case "sub_duration": return { (provider, _, locale) in provider.subscriptionDuration(locale) }
case "sub_offer_duration": return { (provider, _, locale) in provider.introductoryOfferDuration(locale) }
case "sub_offer_price": return { (provider, _, _) in provider.localizedIntroductoryOfferPrice }
case "sub_relative_discount": return { $0.localizedRelativeDiscount($1.discountRelativeToMostExpensivePerMonth,
$2) }

default:
Logger.warning(Strings.unrecognized_variable_name(variableName: variableName))
Expand All @@ -92,8 +115,12 @@ enum VariableHandler {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
extension String {

func processed(with provider: VariableDataProvider, locale: Locale) -> Self {
return VariableHandler.processVariables(in: self, with: provider, locale: locale)
func processed(
with provider: VariableDataProvider,
context: VariableHandler.Context,
locale: Locale
) -> Self {
return VariableHandler.processVariables(in: self, with: provider, context: context, locale: locale)
}

func unrecognizedVariables() -> Set<String> {
Expand All @@ -109,8 +136,12 @@ extension String {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
private extension VariableDataProvider {

func value(for variableName: String, locale: Locale) -> String {
VariableHandler.provider(for: variableName)?(self, locale) ?? ""
func value(
for variableName: String,
context: VariableHandler.Context,
locale: Locale
) -> String {
VariableHandler.provider(for: variableName)?(self, context, locale) ?? ""
}

}
Expand All @@ -123,13 +154,16 @@ private enum VariableHandlerIOS16 {
static func processVariables(
in string: String,
with provider: VariableDataProvider,
context: VariableHandler.Context,
locale: Locale = .current
) -> String {
let matches = Self.extractVariables(from: string)
var replacedString = string

for variableMatch in matches.reversed() {
let replacementValue = provider.value(for: variableMatch.variable, locale: locale)
let replacementValue = provider.value(for: variableMatch.variable,
context: context,
locale: locale)
replacedString = replacedString.replacingCharacters(in: variableMatch.range, with: replacementValue)
}

Expand Down Expand Up @@ -176,6 +210,7 @@ private enum VariableHandlerIOS15 {
static func processVariables(
in string: String,
with provider: VariableDataProvider,
context: VariableHandler.Context,
locale: Locale = .current
) -> String {
var replacedString = string
Expand All @@ -185,7 +220,9 @@ private enum VariableHandlerIOS15 {
let variableNameRange = match.range(at: 1)
if let variableNameRange = Range(variableNameRange, in: string) {
let variableName = String(string[variableNameRange])
let replacementValue = provider.value(for: variableName, locale: locale)
let replacementValue = provider.value(for: variableName,
context: context,
locale: locale)

let adjustedRange = NSRange(
location: variableNameRange.lowerBound.utf16Offset(in: string) - Self.pattern.count / 2,
Expand Down
6 changes: 6 additions & 0 deletions RevenueCatUI/Helpers/Package+VariableDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ extension Package: VariableDataProvider {
}
}

func localizedRelativeDiscount(_ discount: Double?, _ locale: Locale) -> String? {
guard let discount else { return nil }

return Localization.localized(discount: discount, locale: locale)
}

}

// MARK: - Private
Expand Down
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ar.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "شهريا";
"Weekly" = "أسبوعي";
"Lifetime" = "حياة";
"%d%% off" = "خصم %d%%";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/bg.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Месечно";
"Weekly" = "Ежеседмично";
"Lifetime" = "Живот";
"%d%% off" = "%d%% намаление";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ca.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mensual";
"Weekly" = "Setmanalment";
"Lifetime" = "Tota una vida";
"%d%% off" = "%d%% de descompte";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Měsíční";
"Weekly" = "Týdně";
"Lifetime" = "Život";
"%d%% off" = "%d%% sleva";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/da.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Månedlige";
"Weekly" = "Ugentlig";
"Lifetime" = "Livstid";
"%d%% off" = "%d%% rabat";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monatlich";
"Weekly" = "Wöchentlich";
"Lifetime" = "Lebensdauer";
"%d%% off" = "%d %% Rabatt";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/el.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Μηνιαίο";
"Weekly" = "Εβδομαδιαίος";
"Lifetime" = "Διάρκεια Ζωής";
"%d%% off" = "Έκπτωση %d%%";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monthly";
"Weekly" = "Weekly";
"Lifetime" = "Lifetime";
"%d%% off" = "%d%% off";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en_AU.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monthly";
"Weekly" = "Weekly";
"Lifetime" = "Lifetime";
"%d%% off" = "%d%% off";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en_CA.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monthly";
"Weekly" = "Weekly";
"Lifetime" = "Lifetime";
"%d%% off" = "%d%% off";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en_GB.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monthly";
"Weekly" = "Weekly";
"Lifetime" = "Lifetime";
"%d%% off" = "%d%% off";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/en_US.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Monthly";
"Weekly" = "Weekly";
"Lifetime" = "Lifetime";
"%d%% off" = "%d%% off";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/es_419.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mensual";
"Weekly" = "Semanalmente";
"Lifetime" = "Toda la vida";
"%d%% off" = "%d%% de descuento";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/es_ES.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mensual";
"Weekly" = "Semanalmente";
"Lifetime" = "Toda la vida";
"%d%% off" = "%d%% de descuento";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/fi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Kuukausittain";
"Weekly" = "Viikoittain";
"Lifetime" = "Elinikä";
"%d%% off" = "%d%% alennus";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/fr_CA.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mensuel";
"Weekly" = "Hebdomadaire";
"Lifetime" = "Durée de vie";
"%d%% off" = "%d%% de réduction";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/he.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "יַרחוֹן";
"Weekly" = "שְׁבוּעִי";
"Lifetime" = "לכל החיים";
"%d%% off" = "%d%% הנחה";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/hi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "महीने के";
"Weekly" = "साप्ताहिक";
"Lifetime" = "जीवनभर";
"%d%% off" = "%d%% छूट";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/hr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mjesečno";
"Weekly" = "Tjedni";
"Lifetime" = "Doživotno";
"%d%% off" = "%d%% popusta";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/hu.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Havi";
"Weekly" = "Heti";
"Lifetime" = "Élettartam";
"%d%% off" = "%d%% kedvezménnyel";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/id.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Bulanan";
"Weekly" = "Mingguan";
"Lifetime" = "Seumur hidup";
"%d%% off" = "Diskon %d%%";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Mensile";
"Weekly" = "settimanalmente";
"Lifetime" = "Tutta la vita";
"%d%% off" = "Sconto del %d%%";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "毎月";
"Weekly" = "毎週";
"Lifetime" = "一生";
"%d%% off" = "%d%%オフ";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/kk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Ай сайын";
"Weekly" = "Апта сайын";
"Lifetime" = "Өмір кезеңі";
"%d%% off" = "%d%% жеңілдік";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "월간 간행물";
"Weekly" = "주간";
"Lifetime" = "일생";
"%d%% off" = "%d%% 할인";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ms.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Bulanan";
"Weekly" = "Setiap minggu";
"Lifetime" = "Seumur hidup";
"%d%% off" = "%d%% diskaun";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/nl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Maandelijks";
"Weekly" = "Wekelijks";
"Lifetime" = "Levenslang";
"%d%% off" = "%d%% korting";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/no.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Månedlig";
"Weekly" = "Ukentlig";
"Lifetime" = "Livstid";
"%d%% off" = "%d %% rabatt";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/pl.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Miesięczny";
"Weekly" = "Co tydzień";
"Lifetime" = "Dożywotni";
"%d%% off" = "%d%% zniżki";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/pt_BR.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Por mês";
"Weekly" = "Semanalmente";
"Lifetime" = "Vida";
"%d%% off" = "%d%% de desconto";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/pt_PT.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Por mês";
"Weekly" = "Semanalmente";
"Lifetime" = "Vida";
"%d%% off" = "%d%% de desconto";
1 change: 1 addition & 0 deletions RevenueCatUI/Resources/ro.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
"Monthly" = "Lunar";
"Weekly" = "Săptămânal";
"Lifetime" = "Durata de viață";
"%d%% off" = "%d%% reducere";
Loading

0 comments on commit f617fbb

Please sign in to comment.