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.12.6

### Fixes

- Fixes a rare issue where TestFlight products could display in a different currency on the paywall than on Apple's payment sheet.

## 4.12.5

### Enhancements
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Sources/SuperwallKit/Logger/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ enum Logger: Loggable {
dumping["error"] = error
}

var name = "\(Date().isoString) \(logLevel.descriptionEmoji) [Superwall] [\(scope.description)] - \(logLevel.description)"
var name = "\(Date().isoString) \(logLevel.descriptionEmoji) "
+ "[Superwall] [\(scope.description)] - \(logLevel.description)"

if let message = message {
name += ": \(message)"
Expand Down
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.12.5
4.12.6
"""
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@

// block selection
let selectionString =
// swiftlint:disable:next line_length
"var css = '*{-webkit-touch-callout:none;-webkit-user-select:none} .w-webflow-badge { display: none !important; }'; "

Check warning on line 346 in Sources/SuperwallKit/Paywall/View Controller/Web View/Message Handling/PaywallMessageHandler.swift

View workflow job for this annotation

GitHub Actions / Package-SwiftLint

Superfluous Disable Command Violation: SwiftLint rule 'line_length' did not trigger a violation in the disabled region; remove the disable command (superfluous_disable_command)
+ "var head = document.head || document.getElementsByTagName('head')[0]; "
+ "var style = document.createElement('style'); style.type = 'text/css'; "
+ "style.appendChild(document.createTextNode(css)); head.appendChild(style); "
Expand All @@ -355,6 +356,7 @@
self.delegate?.webView.configuration.userContentController.addUserScript(selectionScript)

let preventSelection =
// swiftlint:disable:next line_length
"var css = '*{-webkit-touch-callout:none;-webkit-user-select:none}'; var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(css)); head.appendChild(style);"
self.delegate?.webView.evaluateJavaScript(preventSelection)

Expand Down
17 changes: 12 additions & 5 deletions Sources/SuperwallKit/Storage/Cache/Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,23 @@ class Cache {
guard let self = self else { return }
guard
let documentDirectory = self.fileManager.urls(for: .documentDirectory, in: .userDomainMask).first,
let applicationSupportDirectory = self.fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
let applicationSupportDirectory = self.fileManager.urls(
for: .applicationSupportDirectory,
in: .userDomainMask
).first
else {
return
}

let userSpecificDocumentUrl = documentDirectory.appendingPathComponent(Cache.userSpecificDocumentDirectoryPrefix)
let appSpecificDocumentUrl = documentDirectory.appendingPathComponent(Cache.appSpecificDocumentDirectoryPrefix)
let userSpecificDocumentUrl = documentDirectory
.appendingPathComponent(Cache.userSpecificDocumentDirectoryPrefix)
let appSpecificDocumentUrl = documentDirectory
.appendingPathComponent(Cache.appSpecificDocumentDirectoryPrefix)

let userSpecificSupportUrl = applicationSupportDirectory.appendingPathComponent(Cache.userSpecificDocumentDirectoryPrefix)
let appSpecificSupportUrl = applicationSupportDirectory.appendingPathComponent(Cache.appSpecificDocumentDirectoryPrefix)
let userSpecificSupportUrl = applicationSupportDirectory
.appendingPathComponent(Cache.userSpecificDocumentDirectoryPrefix)
let appSpecificSupportUrl = applicationSupportDirectory
.appendingPathComponent(Cache.appSpecificDocumentDirectoryPrefix)

do {
// Create the destination directories if they don't exist.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ 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 @@ -59,25 +58,7 @@ struct SK2StoreProduct: StoreProductType {
}

var localizedPrice: String {
return priceFormatter(locale: underlyingSK2Product.priceFormatStyle.locale)
.string(from: underlyingSK2Product.price as NSDecimalNumber) ?? "?"
}

var priceFormatter: NumberFormatter? {
guard let currencyCode = self.currencyCode else {
return nil
}
return priceFormatterProvider.priceFormatterForSK2(
withCurrencyCode: currencyCode,
locale: underlyingSK2Product.priceFormatStyle.locale
)
}

private func priceFormatter(locale: Locale) -> NumberFormatter {
let formatter = NumberFormatter()
formatter.locale = underlyingSK2Product.priceFormatStyle.locale
formatter.numberStyle = .currency
return formatter
return underlyingSK2Product.price.formatted(underlyingSK2Product.priceFormatStyle)
}

var localizedSubscriptionPeriod: String {
Expand Down Expand Up @@ -271,87 +252,56 @@ struct SK2StoreProduct: StoreProductType {
}

var dailyPrice: String {
if underlyingSK2Product.price == 0.00 {
return "$0.00"
}

let numberFormatter = NumberFormatter()
let locale = underlyingSK2Product.priceFormatStyle.locale
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale

guard let subscriptionPeriod = underlyingSK2Product.subscription?.subscriptionPeriod else {
return "n/a"
}

let numberOfUnits = subscriptionPeriod.value
var periods: Decimal = 1.0
let inputPrice = underlyingSK2Product.price

if subscriptionPeriod.unit == .year {
switch subscriptionPeriod.unit {
case .year:
periods = Decimal(365 * numberOfUnits)
}

if subscriptionPeriod.unit == .month {
case .month:
periods = Decimal(30 * numberOfUnits)
}

if subscriptionPeriod.unit == .week {
case .week:
periods = Decimal(7 * numberOfUnits)
}

if subscriptionPeriod.unit == .day {
case .day:
periods = Decimal(numberOfUnits)
@unknown default:
periods = Decimal(numberOfUnits)
}

return numberFormatter.string(from: NSDecimalNumber(decimal: inputPrice / periods)) ?? "n/a"
return (inputPrice / periods).formatted(underlyingSK2Product.priceFormatStyle)
}

var weeklyPrice: String {
if underlyingSK2Product.price == 0.00 {
return "$0.00"
}

let numberFormatter = NumberFormatter()
let locale = underlyingSK2Product.priceFormatStyle.locale
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale

guard let subscriptionPeriod = underlyingSK2Product.subscription?.subscriptionPeriod else {
return "n/a"
}

let numberOfUnits = subscriptionPeriod.value
var periods: Decimal = 1.0
let inputPrice = underlyingSK2Product.price

if subscriptionPeriod.unit == .year {
switch subscriptionPeriod.unit {
case .year:
periods = Decimal(52 * numberOfUnits)
}

if subscriptionPeriod.unit == .month {
case .month:
periods = Decimal(4 * numberOfUnits)
}

if subscriptionPeriod.unit == .week {
case .week:
periods = Decimal(numberOfUnits)
}

if subscriptionPeriod.unit == .day {
case .day:
periods = Decimal(numberOfUnits) / Decimal(7)
@unknown default:
periods = Decimal(numberOfUnits)
}

return numberFormatter.string(from: NSDecimalNumber(decimal: inputPrice / periods)) ?? "n/a"
return (inputPrice / periods).formatted(underlyingSK2Product.priceFormatStyle)
}

var monthlyPrice: String {
if underlyingSK2Product.price == 0.00 {
return "$0.00"
}

let numberFormatter = NumberFormatter()
let locale = underlyingSK2Product.priceFormatStyle.locale
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale

guard let subscriptionPeriod = underlyingSK2Product.subscription?.subscriptionPeriod else {
return "n/a"
}
Expand All @@ -360,35 +310,23 @@ struct SK2StoreProduct: StoreProductType {
var periods: Decimal = 1.0
let inputPrice = underlyingSK2Product.price

if subscriptionPeriod.unit == .year {
switch subscriptionPeriod.unit {
case .year:
periods = Decimal(12 * numberOfUnits)
}

if subscriptionPeriod.unit == .month {
case .month:
periods = Decimal(1 * numberOfUnits)
}

if subscriptionPeriod.unit == .week {
case .week:
periods = Decimal(numberOfUnits) / Decimal(4)
}

if subscriptionPeriod.unit == .day {
case .day:
periods = Decimal(numberOfUnits) / Decimal(30)
@unknown default:
periods = Decimal(numberOfUnits)
}

return numberFormatter.string(from: NSDecimalNumber(decimal: inputPrice / periods)) ?? "n/a"
return (inputPrice / periods).formatted(underlyingSK2Product.priceFormatStyle)
}

var yearlyPrice: String {
if underlyingSK2Product.price == 0.00 {
return "$0.00"
}

let numberFormatter = NumberFormatter()
let locale = underlyingSK2Product.priceFormatStyle.locale
numberFormatter.numberStyle = .currency
numberFormatter.locale = locale

guard let subscriptionPeriod = underlyingSK2Product.subscription?.subscriptionPeriod else {
return "n/a"
}
Expand All @@ -397,23 +335,20 @@ struct SK2StoreProduct: StoreProductType {
var periods: Decimal = 1.0
let inputPrice = underlyingSK2Product.price

if subscriptionPeriod.unit == .year {
switch subscriptionPeriod.unit {
case .year:
periods = Decimal(numberOfUnits)
}

if subscriptionPeriod.unit == .month {
case .month:
periods = Decimal(numberOfUnits) / Decimal(12)
}

if subscriptionPeriod.unit == .week {
case .week:
periods = Decimal(numberOfUnits) / Decimal(52)
}

if subscriptionPeriod.unit == .day {
case .day:
periods = Decimal(numberOfUnits) / Decimal(365)
@unknown default:
periods = Decimal(numberOfUnits)
}

return numberFormatter.string(from: NSDecimalNumber(decimal: inputPrice / periods)) ?? "n/a"
return (inputPrice / periods).formatted(underlyingSK2Product.priceFormatStyle)
}

var hasFreeTrial: Bool {
Expand Down Expand Up @@ -452,16 +387,16 @@ struct SK2StoreProduct: StoreProductType {
return futureDate
}

var trialPeriodEndDateString: String {
if let trialPeriodEndDate = trialPeriodEndDate {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
dateFormatter.locale = .autoupdatingCurrent
private static let trialDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
formatter.locale = .autoupdatingCurrent
return formatter
}()

return dateFormatter.string(from: trialPeriodEndDate)
}
return ""
var trialPeriodEndDateString: String {
trialPeriodEndDate.map { Self.trialDateFormatter.string(from: $0) } ?? ""
}

var trialPeriodDays: Int {
Expand Down Expand Up @@ -658,22 +593,22 @@ struct SK2StoreProduct: StoreProductType {

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

let introMonthlyPrice = introductoryDiscount.pricePerUnit(unit)

return priceFormatter?.string(from: NSDecimalNumber(decimal: introMonthlyPrice)) ?? "$0.00"
return introMonthlyPrice.formatted(underlyingSK2Product.priceFormatStyle)
}

var localizedTrialPeriodPrice: String {
guard let price = underlyingSK2Product.subscription?.introductoryOffer?.price else {
return priceFormatter?.string(from: 0.00) ?? "$0.00"
return Decimal(0).formatted(underlyingSK2Product.priceFormatStyle)
}
return priceFormatter?.string(from: price as NSDecimalNumber) ?? "$0.00"
return price.formatted(underlyingSK2Product.priceFormatStyle)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ final class TransactionManager {
} else {
var message = "Transactions Failed to Restore."
if !hasActiveEntitlements && hasRestored {
message +=
" The restoration result is \"restored\" but there are no active entitlements. Ensure the active entitlements are set before confirming successful restoration."
message += " The restoration result is \"restored\" but there are no active "
+ "entitlements. Ensure the active entitlements are set before confirming "
+ "successful restoration."
}
if case .failed(let error) = restorationResult,
let error = error {
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.12.5"
s.version = "4.12.6"
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