Skip to content

Commit

Permalink
Merge pull request #283 from superwall/v4-develop
Browse files Browse the repository at this point in the history
4.0.0-beta.3
  • Loading branch information
yusuftor authored Jan 16, 2025
2 parents 492b396 + f528998 commit d4b2690
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 39 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@

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

## 4.0.0-beta.3

### Breaking Changes

- Renames `PaywallView(event:)` to `PaywallView(placement:)`.

### Fixes

- Adds extra check to get StoreKit 2 transaction data on `transaction_complete`.

## 4.0.0-beta.2

### Fixes

- Fixes an issue to do with audience filters.
- Readds unavailable functions from v3 to make the upgrade path smoother.
- Re-adds unavailable functions from v3 to make the upgrade path smoother.

## 4.0.0-beta.1

Expand Down
2 changes: 1 addition & 1 deletion Sources/SuperwallKit/Config/Options/SuperwallOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public final class SuperwallOptions: NSObject, Encodable {
/// failure before it times out. Defaults to 6.
///
/// Adjust this if you want the SDK to call the ``PaywallPresentationHandler/onError(_:)``
/// handler of the ``PaywallPresentationHandler`` faster when you call ``Superwall/register(event:)``
/// handler of the ``PaywallPresentationHandler`` faster when you call ``Superwall/register(placement:)``
public var maxConfigRetryCount = 6 {
didSet {
// Must be >= 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ The `Superwall` class is used to access all the features of the SDK. Before usin
- `PaywallViewController`
- `PaywallViewControllerDelegate`
- `PaywallViewControllerDelegateObjc`
- `PaywallView`

### Handling Purchases

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func toPassableValue(from anyValue: Any) -> PassableValue {
if let number = anyValue as? NSNumber {
// Check if it is a boolean
if CFGetTypeID(number) == CFBooleanGetTypeID() {
return .bool(number.boolValue)
return .bool(number.boolValue)
}
// If not a boolean, let the switch handle the rest
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SwiftUI

/// A SwiftUI paywall view that you can embed into your app.
///
/// This uses ``Superwall/getPaywall(forEvent:params:paywallOverrides:delegate:)`` under the hood.
/// This uses ``Superwall/getPaywall(forPlacement:params:paywallOverrides:delegate:)`` under the hood.
///
/// - Warning: You're responsible for the deallocation of this view. If you have a `PaywallView` presented somewhere
/// and you try to present the same `PaywallView` elsewhere, you will get a crash.
Expand All @@ -21,10 +21,10 @@ public struct PaywallView<
@State private var hasLoaded = false
@Environment(\.presentationMode) private var presentationMode

/// The name of the event, as you have defined on the Superwall dashboard.
private let event: String
/// The name of the placement, as you have defined on the Superwall dashboard.
private let placement: String

/// Optional parameters you'd like to pass with your event. Defaults to `nil`.
/// Optional parameters you'd like to pass with your placement. Defaults to `nil`.
///
/// These can be referenced within the rules
/// of your campaign. Keys beginning with `$` are reserved for Superwall and will be dropped. Values can be any
Expand Down Expand Up @@ -60,11 +60,11 @@ public struct PaywallView<

/// A SwiftUI paywall view that you can embed into your app.
///
/// This uses ``Superwall/getPaywall(forEvent:params:paywallOverrides:delegate:)`` under the hood.
/// This uses ``Superwall/getPaywall(forPlacement:params:paywallOverrides:delegate:)`` under the hood.
///
/// - Parameters:
/// - event: The name of the event, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your event. These can be referenced within the rules
/// - placement: The name of the placement, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your placement. These can be referenced within the rules
/// of your campaign. Keys beginning with `$` are reserved for Superwall and will be dropped. Values can be any
/// JSON encodable value, URLs or Dates. Arrays and dictionaries as values are not supported at this time, and will
/// be dropped.
Expand All @@ -84,15 +84,15 @@ public struct PaywallView<
/// - Warning: You're responsible for the deallocation of this view. If you have a `PaywallView` presented somewhere
/// and you try to present the same `PaywallView` elsewhere, you will get a crash.
public init(
event: String,
placement: String,
params: [String: Any]? = nil,
paywallOverrides: PaywallOverrides? = nil,
onRequestDismiss: ((PaywallInfo, PaywallResult) -> Void)? = nil,
onSkippedView: ((PaywallSkippedReason) -> OnSkippedView)? = nil,
onErrorView: ((Error) -> OnErrorView)? = nil,
feature: (() -> Void)? = nil
) {
self.event = event
self.placement = placement
self.params = params
self.paywallOverrides = paywallOverrides
self.onRequestDismiss = onRequestDismiss
Expand Down Expand Up @@ -140,7 +140,7 @@ public struct PaywallView<
hasLoaded = true
Task {
await manager.getPaywall(
forPlacement: event,
forPlacement: placement,
params: params,
paywallOverrides: paywallOverrides
)
Expand All @@ -154,10 +154,10 @@ public struct PaywallView<
extension PaywallView where OnSkippedView == Never, OnErrorView == Never {
/// A SwiftUI paywall view that you can embed into your app.
///
/// This uses ``Superwall/getPaywall(forEvent:params:paywallOverrides:delegate:)`` under the hood.
/// This uses ``Superwall/getPaywall(forPlacement:params:paywallOverrides:delegate:)`` under the hood.
///
/// - Parameters:
/// - event: The name of the event, as you have defined on the Superwall dashboard.
/// - placement: The name of the placement, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your event. These can be referenced within the rules
/// of your campaign. Keys beginning with `$` are reserved for Superwall and will be dropped. Values can be any
/// JSON encodable value, URLs or Dates. Arrays and dictionaries as values are not supported at this time, and will
Expand All @@ -174,13 +174,13 @@ extension PaywallView where OnSkippedView == Never, OnErrorView == Never {
/// - Warning: You're responsible for the deallocation of this view. If you have a `PaywallView` presented somewhere
/// and you try to present the same `PaywallView` elsewhere, you will get a crash.
public init(
event: String,
placement: String,
params: [String: Any]? = nil,
paywallOverrides: PaywallOverrides? = nil,
onRequestDismiss: ((PaywallInfo, PaywallResult) -> Void)? = nil,
feature: (() -> Void)? = nil
) {
self.event = event
self.placement = placement
self.params = params
self.paywallOverrides = paywallOverrides
self.onErrorView = nil
Expand All @@ -194,11 +194,11 @@ extension PaywallView where OnSkippedView == Never, OnErrorView == Never {
extension PaywallView where OnSkippedView == Never {
/// A SwiftUI paywall view that you can embed into your app.
///
/// This uses ``Superwall/getPaywall(forEvent:params:paywallOverrides:delegate:)`` under the hood.
/// This uses ``Superwall/getPaywall(forPlacement:params:paywallOverrides:delegate:)`` under the hood.
///
/// - Parameters:
/// - event: The name of the event, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your event. These can be referenced within the rules
/// - placement: The name of the placement, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your placement. These can be referenced within the rules
/// of your campaign. Keys beginning with `$` are reserved for Superwall and will be dropped. Values can be any
/// JSON encodable value, URLs or Dates. Arrays and dictionaries as values are not supported at this time, and will
/// be dropped.
Expand All @@ -216,14 +216,14 @@ extension PaywallView where OnSkippedView == Never {
/// - Warning: You're responsible for the deallocation of this view. If you have a `PaywallView` presented somewhere
/// and you try to present the same `PaywallView` elsewhere, you will get a crash.
public init(
event: String,
placement: String,
params: [String: Any]? = nil,
paywallOverrides: PaywallOverrides? = nil,
onRequestDismiss: ((PaywallInfo, PaywallResult) -> Void)? = nil,
onErrorView: @escaping (Error) -> OnErrorView,
feature: (() -> Void)? = nil
) {
self.event = event
self.placement = placement
self.params = params
self.paywallOverrides = paywallOverrides
self.onRequestDismiss = onRequestDismiss
Expand All @@ -237,11 +237,11 @@ extension PaywallView where OnSkippedView == Never {
extension PaywallView where OnErrorView == Never {
/// A SwiftUI paywall view that you can embed into your app.
///
/// This uses ``Superwall/getPaywall(forEvent:params:paywallOverrides:delegate:)`` under the hood.
/// This uses ``Superwall/getPaywall(forPlacement:params:paywallOverrides:delegate:)`` under the hood.
///
/// - Parameters:
/// - event: The name of the event, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your event. These can be referenced within the rules
/// - placement: The name of the placement, as you have defined on the Superwall dashboard.
/// - params: Optional parameters you'd like to pass with your placement. These can be referenced within the rules
/// of your campaign. Keys beginning with `$` are reserved for Superwall and will be dropped. Values can be any
/// JSON encodable value, URLs or Dates. Arrays and dictionaries as values are not supported at this time, and will
/// be dropped.
Expand All @@ -261,14 +261,14 @@ extension PaywallView where OnErrorView == Never {
/// - Warning: You're responsible for the deallocation of this view. If you have a `PaywallView` presented somewhere
/// and you try to present the same `PaywallView` elsewhere, you will get a crash.
public init(
event: String,
placement: String,
params: [String: Any]? = nil,
paywallOverrides: PaywallOverrides? = nil,
onRequestDismiss: ((PaywallInfo, PaywallResult) -> Void)? = nil,
onSkippedView: @escaping (PaywallSkippedReason) -> OnSkippedView,
feature: (() -> Void)? = nil
) {
self.event = event
self.placement = placement
self.params = params
self.paywallOverrides = paywallOverrides
self.onErrorView = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ final class PurchaseManager: Purchasing {
identityManager: identityManager,
receiptManager: receiptManager,
storage: storage,
coordinator: coordinator,
factory: factory
)
_sk2TransactionListener = SK2TransactionListener(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,21 @@ actor PurchasingCoordinator {
result: PurchaseResult
) async {
let transaction = await factory.makeStoreTransaction(from: transaction)
completePurchase(of: transaction, result: result)
storeTransaction(transaction, result: result)
completion?(result)
}

@available(iOS 15.0, *)
func completePurchase(
of transaction: SK2Transaction,
func storeTransaction(
_ transaction: SK2Transaction,
result: PurchaseResult
) async {
let transaction = await factory.makeStoreTransaction(from: transaction)
completePurchase(of: transaction, result: result)
storeTransaction(transaction, result: result)
}

private func completePurchase(
of transaction: StoreTransaction,
private func storeTransaction(
_ transaction: StoreTransaction,
result: PurchaseResult
) {
if result == .purchased {
Expand All @@ -170,7 +171,6 @@ actor PurchasingCoordinator {
}
}
lastInternalTransaction = transaction
completion?(result)
}

func reset() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ extension ProductPurchaserSK1: SKPaymentTransactionObserver {
)
if !isExistingTransaction {
let transactionManager = factory.makeTransactionManager()
await transactionManager.observeTransaction(for: skTransaction.payment.productIdentifier)
await transactionManager.observeSK1Transaction(for: skTransaction.payment.productIdentifier)
storedIds.insert(skTransaction.payment.productIdentifier)
storage.save(storedIds, forType: PurchasingProductIds.self)
}
Expand Down Expand Up @@ -262,7 +262,8 @@ extension ProductPurchaserSK1: SKPaymentTransactionObserver {
}
await coordinator.completePurchase(
of: skTransaction,
result: .failed(error))
result: .failed(error)
)
}
case .deferred:
finishTransaction(skTransaction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import StoreKit
final class ProductPurchaserSK2: Purchasing {
private unowned let identityManager: IdentityManager
private unowned let receiptManager: ReceiptManager
private let coordinator: PurchasingCoordinator
private unowned let factory: Factory
typealias Factory = HasExternalPurchaseControllerFactory
& OptionsFactory
Expand All @@ -30,10 +31,12 @@ final class ProductPurchaserSK2: Purchasing {
identityManager: IdentityManager,
receiptManager: ReceiptManager,
storage: Storage,
coordinator: PurchasingCoordinator,
factory: Factory
) {
self.identityManager = identityManager
self.receiptManager = receiptManager
self.coordinator = coordinator
self.factory = factory

if #available(iOS 17.2, *) {
Expand Down Expand Up @@ -105,10 +108,14 @@ final class ProductPurchaserSK2: Purchasing {
case let .success(.verified(transaction)):
await transaction.finish()
await receiptManager.loadPurchasedProducts()
return .purchased
let result = PurchaseResult.purchased
await coordinator.storeTransaction(transaction, result: result)
return result
case let .success(.unverified(transaction, error)):
await transaction.finish()
return .failed(error)
let result = PurchaseResult.failed(error)
await coordinator.storeTransaction(transaction, result: result)
return result
case .userCancelled:
return .cancelled
case .pending:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ final class TransactionManager {
}
}

func observeTransaction(for productId: String) async {
func observeSK1Transaction(for productId: String) async {
guard
let storeProduct = try? await productsManager.products(
identifiers: [productId],
Expand Down

0 comments on commit d4b2690

Please sign in to comment.