Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The changelog for `SuperwallKit`. Also see the [releases](https://github.com/superwall/Superwall-iOS/releases) on GitHub.

## 4.14.3

### Fixes

- Fixed computed period prices (`weeklyPrice`, `dailyPrice`, `monthlyPrice`, `yearlyPrice`) displaying incorrectly rounded values on StoreKit 2 in production. For example, a £4.99/week product could show as £5.00/week. This was caused by Apple's `priceFormatStyle` applying storefront-specific rounding to computed values.

## 4.14.2

### Enhancements
Expand Down
24 changes: 12 additions & 12 deletions Examples/Advanced/Advanced/Superwall_Advanced-Products.storekit
Original file line number Diff line number Diff line change
Expand Up @@ -17,55 +17,51 @@

],
"settings" : {
"_askToBuyEnabled" : false,
"_billingGracePeriodEnabled" : false,
"_billingIssuesEnabled" : false,
"_compatibilityTimeRate" : {
"3" : 6
},
"_disableDialogs" : false,
"_failTransactionsEnabled" : false,
"_locale" : "en_US",
"_renewalBillingIssuesEnabled" : false,
"_storefront" : "USA",
"_storeKitErrors" : [
{
"current" : null,
"enabled" : false,
"name" : "Load Products"
},
{
"current" : null,
"enabled" : false,
"name" : "Purchase"
},
{
"current" : null,
"enabled" : false,
"name" : "Verification"
},
{
"current" : null,
"enabled" : false,
"name" : "App Store Sync"
},
{
"current" : null,
"enabled" : false,
"name" : "Subscription Status"
},
{
"current" : null,
"enabled" : false,
"name" : "App Transaction"
},
{
"current" : null,
"enabled" : false,
"name" : "Manage Subscriptions Sheet"
},
{
"current" : null,
"enabled" : false,
"name" : "Refund Request Sheet"
},
{
"current" : null,
"enabled" : false,
"name" : "Offer Code Redeem Sheet"
}
Expand All @@ -91,7 +87,9 @@
"familyShareable" : false,
"groupNumber" : 1,
"internalID" : "38D8615F",
"introductoryOffer" : null,
"introductoryOffers" : [

],
"localizations" : [
{
"description" : "Access to diamond features",
Expand Down Expand Up @@ -119,7 +117,9 @@
"familyShareable" : false,
"groupNumber" : 2,
"internalID" : "E02B772A",
"introductoryOffer" : null,
"introductoryOffers" : [

],
"localizations" : [
{
"description" : "Access to pro features",
Expand All @@ -140,7 +140,7 @@
}
],
"version" : {
"major" : 4,
"major" : 5,
"minor" : 0
}
}
2 changes: 1 addition & 1 deletion Sources/SuperwallKit/Misc/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ let sdkVersion = """
*/

let sdkVersion = """
4.14.2
4.14.3
"""
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import StoreKit

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, *)
struct SK2StoreProduct: StoreProductType {
private let priceFormatterProvider = PriceFormatterProvider()
let entitlements: Set<Entitlement>

init(
Expand Down Expand Up @@ -61,6 +62,16 @@ struct SK2StoreProduct: StoreProductType {
return underlyingSK2Product.price.formatted(underlyingSK2Product.priceFormatStyle)
}

/// A `NumberFormatter` for formatting computed prices (daily, weekly, monthly, yearly).
/// Unlike `priceFormatStyle`, this does not apply storefront-specific rounding
/// that can cause values like £4.99 to display as £5.00 in production.
private var priceFormatter: NumberFormatter {
priceFormatterProvider.priceFormatterForSK2(
withCurrencyCode: underlyingSK2Product.priceFormatStyle.currencyCode,
locale: underlyingSK2Product.priceFormatStyle.locale
)
}

var localizedSubscriptionPeriod: String {
guard let subscriptionPeriod = underlyingSK2Product.subscription?.subscriptionPeriod else {
return ""
Expand Down Expand Up @@ -273,7 +284,8 @@ struct SK2StoreProduct: StoreProductType {
periods = Decimal(numberOfUnits)
}

return (inputPrice / periods).roundedPrice().formatted(underlyingSK2Product.priceFormatStyle)
let result = (inputPrice / periods).roundedPrice()
return priceFormatter.string(from: NSDecimalNumber(decimal: result)) ?? "n/a"
}

var weeklyPrice: String {
Expand All @@ -298,7 +310,8 @@ struct SK2StoreProduct: StoreProductType {
periods = Decimal(numberOfUnits)
}

return (inputPrice / periods).roundedPrice().formatted(underlyingSK2Product.priceFormatStyle)
let result = (inputPrice / periods).roundedPrice()
return priceFormatter.string(from: NSDecimalNumber(decimal: result)) ?? "n/a"
}

var monthlyPrice: String {
Expand All @@ -323,7 +336,8 @@ struct SK2StoreProduct: StoreProductType {
periods = Decimal(numberOfUnits)
}

return (inputPrice / periods).roundedPrice().formatted(underlyingSK2Product.priceFormatStyle)
let result = (inputPrice / periods).roundedPrice()
return priceFormatter.string(from: NSDecimalNumber(decimal: result)) ?? "n/a"
}

var yearlyPrice: String {
Expand All @@ -348,7 +362,8 @@ struct SK2StoreProduct: StoreProductType {
periods = Decimal(numberOfUnits)
}

return (inputPrice / periods).roundedPrice().formatted(underlyingSK2Product.priceFormatStyle)
let result = (inputPrice / periods).roundedPrice()
return priceFormatter.string(from: NSDecimalNumber(decimal: result)) ?? "n/a"
}

var hasFreeTrial: Bool {
Expand Down Expand Up @@ -593,15 +608,15 @@ struct SK2StoreProduct: StoreProductType {

func trialPeriodPricePerUnit(_ unit: SubscriptionPeriod.Unit) -> String {
guard let introductoryDiscount = introductoryDiscount else {
return Decimal(0).formatted(underlyingSK2Product.priceFormatStyle)
return priceFormatter.string(from: 0.00) ?? "n/a"
}
if introductoryDiscount.price == 0.00 {
return Decimal(0).formatted(underlyingSK2Product.priceFormatStyle)
return priceFormatter.string(from: 0.00) ?? "n/a"
}

let introMonthlyPrice = introductoryDiscount.pricePerUnit(unit)

return introMonthlyPrice.formatted(underlyingSK2Product.priceFormatStyle)
return priceFormatter.string(from: NSDecimalNumber(decimal: introMonthlyPrice)) ?? "n/a"
}

var localizedTrialPeriodPrice: String {
Expand Down
2 changes: 1 addition & 1 deletion SuperwallKit.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "SuperwallKit"
s.version = "4.14.2"
s.version = "4.14.3"
s.summary = "Superwall: In-App Paywalls Made Easy"
s.description = "Paywall infrastructure for mobile apps :) we make things like editing your paywall and running price tests as easy as clicking a few buttons. superwall.com"

Expand Down
Loading