Skip to content

Paywalls: added support for purchasing#2812

Merged
NachoSoto merged 3 commits into
paywallsfrom
paywall-purchasing
Jul 14, 2023
Merged

Paywalls: added support for purchasing#2812
NachoSoto merged 3 commits into
paywallsfrom
paywall-purchasing

Conversation

@NachoSoto

Copy link
Copy Markdown
Contributor

This adds a new PurchaseHandler type, which can be instantiated with Purchases or with a mock implementation for previews. That gets injected, and templates can now purchase and dismiss themselves.

I've improved the SimpleApp setup to better work with the lifetime of purchases. Now it only displays the paywall if the user doesn't have an entitlement.

I've also added some basic error handling to the new AsyncButton:
Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32 06

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work regardless of how users display PaywallView:
Per the docs, it can:

  • Dismiss a modal presentation, like a sheet or a popover.
  • Pop the current view from a `NavigationStack
  • Close a window that you create with WindowGroup

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming they're presenting a full-screen paywall, that is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meaning that if it's an embedded view it'd be awkward and could lead to unexpected behaviors

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to act on this now but we should start thinking about how we'll manage embeddable views

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, especially from what we talked about today.
Especially for that I think we should add a sort of "event handler" / SwiftUI property like StoreKit views.

@NachoSoto NachoSoto force-pushed the paywall-purchasing branch 2 times, most recently from 33c3447 to 5f9c427 Compare July 13, 2023 22:52
@NachoSoto NachoSoto force-pushed the paywalls-filter-tests branch from db1e346 to 550d462 Compare July 13, 2023 22:54
@NachoSoto NachoSoto force-pushed the paywall-purchasing branch from 5f9c427 to 75d3f8a Compare July 13, 2023 22:54
Comment on lines 21 to 22

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a placeholder view that can present a sheet.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Displayed automatically.

Comment on lines 18 to 41

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is this simple screen:
simulator_screenshot_4F32B1F0-9F4A-4DBE-8821-0233B1540DEF

Comment thread RevenueCatUI/Views/AsyncButton.swift Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The good thing about these being our own errors is that we can even improve this error handling.
Eventually we should provide localizations for each of our errors too.

@codecov

codecov Bot commented Jul 14, 2023

Copy link
Copy Markdown

Codecov Report

Merging #2812 (0115490) into paywalls (302e03f) will decrease coverage by 0.11%.
The diff coverage is n/a.

❗ Current head 0115490 differs from pull request most recent head 7b812f1. Consider uploading reports for the commit 7b812f1 to get more accurate results

@@             Coverage Diff              @@
##           paywalls    #2812      +/-   ##
============================================
- Coverage     86.38%   86.28%   -0.11%     
============================================
  Files           216      216              
  Lines         15557    15557              
============================================
- Hits          13439    13423      -16     
- Misses         2118     2134      +16     

see 5 files with indirect coverage changes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming they're presenting a full-screen paywall, that is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meaning that if it's an embedded view it'd be awkward and could lead to unexpected behaviors

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to act on this now but we should start thinking about how we'll manage embeddable views

Comment thread RevenueCatUI/Views/AsyncButton.swift Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll have to make this text configurable at one point

Comment thread RevenueCatUI/PaywallView.swift Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we might have to rethink the naming for these at one point to minimize collisions with paywalls a customer might already have.

Like, say you have a paywall in place and are looking to migrate into ours, it'd suck if you have to rename or remove the one you already have right away in order to test out our SDK

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'd say before we merge this and ship it, we can go through the entire public API (won't be much) and make sure it's solid and documentation is good.

@NachoSoto NachoSoto force-pushed the paywalls-filter-tests branch from 550d462 to c0bbdaa Compare July 14, 2023 21:26
Base automatically changed from paywalls-filter-tests to paywalls July 14, 2023 21:26
This adds a new `PurchaseHandler` type, which can be instantiated with `Purchases` or with a mock implementation for previews.
That gets injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of purchases. Now it only displays the paywall if the user doesn't have an entitlement.
@NachoSoto NachoSoto force-pushed the paywall-purchasing branch from 4d463c5 to 7b812f1 Compare July 14, 2023 21:44
@NachoSoto NachoSoto merged commit 11e9789 into paywalls Jul 14, 2023
@NachoSoto NachoSoto deleted the paywall-purchasing branch July 14, 2023 21:45
NachoSoto added a commit that referenced this pull request Jul 17, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 18, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 18, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 20, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 23, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 24, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 24, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 25, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 26, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 27, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Jul 31, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 3, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 7, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 9, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 11, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 14, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 17, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 24, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 28, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Aug 31, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 1, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 6, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 6, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 6, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 7, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 8, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 14, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 14, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 15, 2023
This adds a new `PurchaseHandler` type, which can be instantiated with
`Purchases` or with a mock implementation for previews. That gets
injected, and templates can now purchase and dismiss themselves.

I've improved the `SimpleApp` setup to better work with the lifetime of
purchases. Now it only displays the paywall if the user doesn't have an
entitlement.

I've also added some basic error handling to the new `AsyncButton`:
![Simulator Screenshot - iPhone 14 Pro - 2023-07-13 at 15 32
06](https://github.com/RevenueCat/purchases-ios/assets/685609/e8c2e6e3-f1e0-411f-9ca2-8a3cc3823a42)
NachoSoto added a commit that referenced this pull request Sep 15, 2023
**This is an automatic release.**
### New Features
#### ✨ Introducing RevenueCatUI 📱

RevenueCat's Paywalls allow you to to remotely configure your entire
paywall view without any code changes or app updates.
Our paywall templates use native code to deliver smooth, intuitive
experiences to your customers when you’re ready to deliver them an
Offering; and you can use our Dashboard to pick the right template and
configuration to meet your needs.

To use RevenueCat Paywalls on iOS, simply:

1. Create a Paywall on the Dashboard for the `Offering` you intend to
serve to your customers
2. Add the `RevenueCatUI` SPM dependency to your project
3. `import RevenueCatUI` at the point in the user experience when you
want to display a paywall:

```swift
import RevenueCatUI
import SwiftUI

struct YourApp: View {

    var body: some View {
        YourContent()
            .presentPaywallIfNeeded(
                requiredEntitlementIdentifier: "pro",
                purchaseCompleted: { customerInfo in
                    print("Purchase completed: \(customerInfo)")
                },
                restoreCompleted: { customerInfo in
                    print("Purchases restored: \(customerInfo)")
                }
            )
    }

}
```

You can find more information in [our
documentation](https://rev.cat/paywalls).

<details>

<summary>List of changes</summary>
* NachoSoto: `Paywalls`: renamed `PaywallEvent.view` to `.impression`
(#3212)
* NachoSoto: `Paywalls`: loading indicator for in-progress purchases
(#3217)
*  NachoSoto: `Paywalls`: fixed template 4 bottom padding (#3211)
* NachoSoto: `Paywalls`: only pre-warm images/intro-eligibility for
`Offerings.current` (#3210)
* NachoSoto: `Paywalls`: fixed mock intro eligibility on snapshot tests
(#3205)
*  NachoSoto: `Paywalls`: fixed SimpleApp release build (#3203)
*  NachoSoto: `Paywalls`: improved `DebugErrorView` layout (#3204)
* NachoSoto: `Paywalls`: refactored `PurchaseHandler` extracting
protocol (#3196)
*  NachoSoto: `Paywalls`: automatically flush events (#3177)
* NachoSoto: `Paywalls`: fixed `TemplateBackgroundImageView` aspect
ratio (#3201)
*  NachoSoto: `Paywalls`: fixed broken layout on template 4 (#3202)
*  NachoSoto: `Paywalls`: events unit and integration tests (#3169)
*  NachoSoto: `Paywalls`: send events to `Purchases` (#3164)
*  NachoSoto: `Paywalls`: convert empty images into `nil` (#3195)
*  NachoSoto: `Paywalls`: new `onRestoreCompleted` handler (#3190)
* NachoSoto: `Paywalls`: fixed `IntroEligibilityViewModel` data lifetime
(#3194)
* NachoSoto: `Paywalls`: test plan for running non-snapshot tests
(#3188)
*  NachoSoto: `Paywalls`: polish template 4 (#3183)
* NachoSoto: `Paywalls`: fixed data flow resulting in multiple
`PurchaseHandler` instances (#3187)
* Cesar de la Vega: `Paywalls`: update `blurred_background_image` key in
`PaywallData` test fixture (#3186)
*  NachoSoto: `Paywalls`: added `Purchases.track(paywallEvent:)` (#3160)
* NachoSoto: `Paywalls`: don't apply dark appearance with no dark mode
colors (#3184)
* NachoSoto: `Paywalls`: fixed template 2 + `.condensedFooter` + iPad
(#3185)
* NachoSoto: `Paywalls`: new `{{ sub_duration_in_months }}` variable
(#3173)
*  NachoSoto: `Paywalls`: created `PaywallEventsManager` (#3159)
* NachoSoto: `Paywalls`: implemented `PostPaywallEventsOperation`
(#3158)
* NachoSoto: `Paywalls`: new `{{ sub_relative_discount }}` variable
(#3131)
*  Charlie Chapman: `Paywalls`: improved `FooterView` (#3171)
* NachoSoto: `Paywalls`: fixed `FooterView` horizontal centering (#3172)
*  NachoSoto: `Paywalls`: created `PaywallEventStore` (#3157)
*  NachoSoto: `Paywalls`: add `PaywallEvent` model (#3156)
*  NachoSoto: `Paywalls`: add `PaywallData.revision` (#3155)
* NachoSoto: `Paywalls`: support fuzzy-Locale search in `iOS 15` (#3162)
* NachoSoto: `PaywallData`: added `@NonEmptyString` to `subtitle` and
`offerName` (#3150)
* NachoSoto: `Paywalls`: add paywall for Load Shedder integration tests
(#3151)
* NachoSoto: `Paywalls`: fixed error view being displayed on release
builds (#3141)
* NachoSoto: `Paywalls`: improved `{{ total_price_and_per_month }}` to
include period (#3136)
* NachoSoto: `Paywalls`: `{{ price_per_period }}` now takes
`SubscriptionPeriod.value` into account (#3133)
*  NachoSoto: `Paywalls`: add Arabic to SimpleApp for testing (#3132)
* NachoSoto: `Paywalls`: update snapshot generation with new separate
git repo (#3116)
*  NachoSoto: `Paywalls`: add support for CTA button gradients (#3121)
*  NachoSoto: `Paywalls`: template 5 (#3095)
* NachoSoto: `Paywalls`: replaced submodule with `gitignore`d reference
(#3125)
* NachoSoto: `Catalyst`: fixed a couple of Catalyst build warnings
(#3120)
* NachoSoto: `Paywalls`: reference test snapshots from submodule (#3115)
*  NachoSoto: `Paywalls`: removed `presentedPaywallViewMode` (#3109)
* NachoSoto: `Paywalls`: remove duplicate `RevenueCat` scheme to fix
Carthage (#3105)
*  NachoSoto: `Paywalls`: fixed iOS 12 build (#3104)
*  NachoSoto: `Paywalls`: fixed template 2 inconsistent spacing (#3091)
*  NachoSoto: `Paywalls`: improved test custom paywall (#3089)
*  NachoSoto: `Paywalls`: avoid warming up cache multiple times (#3068)
*  NachoSoto: `Paywalls`: added all localization (#3080)
* NachoSoto: `Paywalls`: temporarily disable `PaywallTemplate.template4`
(#3088)
*  NachoSoto: `Paywalls`: enabled `Catalyst` support (#3087)
*  NachoSoto: `Paywalls`: iPad polish (#3061)
*  NachoSoto: `Paywalls`: added MIT license to all headers (#3084)
* NachoSoto: `Paywalls`: improved unselected package background color
(#3079)
*  NachoSoto: `Paywalls`: handle already purchased state (#3046)
* NachoSoto: `Paywalls`: only dismiss `PaywallView` when explicitly
presenting it with `.presentPaywallIfNeeded` (#3075)
* NachoSoto: `Paywalls`: add support for generating snapshots on CI
(#3055)
* NachoSoto: `Paywalls`: removed unnecessary `PaywallFooterView` (#3064)
* Josh Holtz: `Paywalls`: new `PaywallFooterView` to replace `modes`
(#3051)
*  Josh Holtz: `Paywalls`: rename card to footer (#3049)
* NachoSoto: `Paywalls`: changed `total_price_and_per_month` to include
period (#3044)
* NachoSoto: `Paywalls`: internal documentation for implementing
templates (#3053)
*  NachoSoto: `Paywalls`: finished `iOS 15` support (#3043)
* NachoSoto: `Paywalls`: validate `PaywallData` to ensure displayed data
is always correct (#3019)
* NachoSoto: `Paywalls`: fixed `total_price_and_per_month` for custom
monthly packages (#3027)
*  NachoSoto: `Paywalls`: tweaking colors on template 2&3 (#3011)
*  NachoSoto: `Paywalls`: changed snapshots to scale 1 (#3016)
* NachoSoto: `Paywalls`: replaced `defaultLocale` with
`preferredLocales` (#3003)
* NachoSoto: `Paywalls`: improved `PaywallDisplayMode.condensedCard`
layout (#3001)
*  NachoSoto: `Paywalls`: `.card` and `.condensedCard` modes (#2995)
*  NachoSoto: `Paywalls`: prevent multiple concurrent purchases (#2991)
*  NachoSoto: `Paywalls`: improved variable warning (#2984)
*  NachoSoto: `Paywalls`: fixed horizontal padding on template 1 (#2987)
* NachoSoto: `Paywalls`: changed `FooterView` to always use `text1`
color (#2992)
*  NachoSoto: `Paywalls`: retry test failures (#2985)
* NachoSoto: `Paywalls`: send presented `PaywallViewMode` with purchases
(#2859)
*  NachoSoto: `Paywalls`: added support for custom fonts (#2988)
* NachoSoto: `Paywalls`: improved template 2 unselected packages (#2982)
* Josh Holtz: `Paywalls`: fix template 2 selected text offer details
color (#2975)
*  NachoSoto: `Paywalls`: warm-up image cache (#2978)
*  NachoSoto: `Paywalls`: extracted `PaywallCacheWarming` (#2977)
*  NachoSoto: `Paywalls`: fixed color in template 3 (#2980)
*  NachoSoto: `Paywalls`: improved default template (#2973)
*  NachoSoto: `Paywalls`: added links to documentation (#2974)
*  NachoSoto: `Paywalls`: updated template names (#2971)
*  NachoSoto: `Paywalls`: updated variable names (#2970)
* NachoSoto: `Paywalls`: added JSON debug screen to
`debugRevenueCatOverlay` (#2972)
*  NachoSoto: `Paywalls`: multi-package horizontal template  (#2949)
*  NachoSoto: `Paywalls`: fixed template 3 icon aspect ratio (#2969)
*  NachoSoto: `Paywalls`: iOS 17 tests on CI (#2955)
*  NachoSoto: `Paywalls`: deploy `debug` sample app (#2966)
*  NachoSoto: `Paywalls`: sort offerings list in sample app (#2965)
*  NachoSoto: `Paywalls`: initial iOS 15 support (#2933)
* NachoSoto: `Paywalls`: changed default `PaywallData` to display
available packages (#2964)
*  NachoSoto: `Paywalls`: changed `offerDetails` to be optional (#2963)
*  NachoSoto: `Paywalls`: markdown support (#2961)
*  NachoSoto: `Paywalls`: updated icon set to match frontend (#2962)
*  NachoSoto: `Paywalls`: added support for `PackageType.custom` (#2959)
* NachoSoto: `Paywalls`: fixed `tvOS` compilation by making it
explicitly unavailable (#2956)
* NachoSoto: `Paywalls`: fix crash when computing localization with
duplicate packages (#2958)
*  NachoSoto: `Paywalls`: UIKit `PaywallViewController` (#2934)
* NachoSoto: `Paywalls`: `presentPaywallIfNecessary` ->
`presentPaywallIfNeeded` (#2953)
* NachoSoto: `Paywalls`: added support for custom and lifetime products
(#2941)
* NachoSoto: `Paywalls`: changed `SamplePaywallsList` to work offline
(#2937)
* NachoSoto: `Paywalls`: fixed header image mask on first template
(#2936)
*  NachoSoto: `Paywalls`: new `subscription_duration` variable (#2942)
* NachoSoto: `Paywalls`: removed `mode` parameter from
`presentPaywallIfNecessary` (#2940)
*  NachoSoto: `Paywalls`: improved `RemoteImage` error layout (#2939)
* NachoSoto: `Paywalls`: added default close button when using
`presentPaywallIfNecessary` (#2935)
* NachoSoto: `Paywalls`: added ability to preview templates in a
`.sheet` (#2938)
*  NachoSoto: `Paywalls`: avoid recomputing variable `Regex` (#2944)
*  NachoSoto: `Paywalls`: improved `FooterView` scaling (#2948)
* NachoSoto: `Paywalls`: added ability to calculate and localize
subscription discounts (#2943)
*  NachoSoto: `Offering`: improved description (#2912)
*  NachoSoto: `Paywalls`: fixed `FooterView` color in template 1 (#2951)
*  NachoSoto: `Paywalls`: fixed `View.scrollableIfNecessary` (#2947)
* NachoSoto: `Paywalls`: improved `IntroEligibilityStateView` to avoid
layout changes (#2946)
* NachoSoto: `Paywalls`: updated offerings snapshot with new asset base
URL (#2950)
* NachoSoto: `Paywalls`: extracted `TemplateBackgroundImageView` (#2945)
*  NachoSoto: `Paywalls`: more polish from design feedback (#2932)
*  NachoSoto: `Paywalls`: more unit tests for purchasing state (#2931)
*  NachoSoto: `Paywalls`: new `.onPurchaseCompleted` modifier (#2930)
* NachoSoto: `Paywalls`: fixed `LoadingPaywallView` displaying a
progress view (#2929)
* NachoSoto: `Paywalls`: added default template to `SamplePaywallsList`
(#2928)
*  NachoSoto: `Paywalls`: added a few more logs (#2927)
*  NachoSoto: `Paywalls` added individual previews for templates (#2924)
*  NachoSoto: `Paywalls`: improved default paywall configuration (#2926)
* NachoSoto: `Paywalls`: moved purchasing state to `PurchaseHandler`
(#2923)
*  NachoSoto: `Paywalls`: updated Integration Test snapshot (#2921)
* NachoSoto: `Paywalls`: pre-warm intro eligibility in background thread
(#2925)
*  NachoSoto: `Paywalls`: removed "couldn't find package" log (#2922)
* NachoSoto: `Paywalls`: SimpleApp reads API key from Xcode Cloud
environment (#2919)
* NachoSoto: `Paywalls`: improved template accessibility support (#2920)
* NachoSoto: `Paywalls`: work around SwiftUI bug to allow embedding
`PaywallView` inside `NavigationStack` (#2918)
*  NachoSoto: `Paywalls`: some basic polish from design feedback (#2917)
* NachoSoto: `Paywalls`: added `OfferingsList` to preview all paywalls
(#2916)
* NachoSoto: `Paywalls`: fixed tappable area for a couple of buttons
(#2915)
*  NachoSoto: `Paywalls`: new `text1` and `text2` colors (#2903)
* NachoSoto: `Paywalls`: updated multi-package bold template design
(#2908)
*  NachoSoto: `Paywalls`: added sample paywalls to `SimpleApp` (#2907)
*  NachoSoto: `Paywalls`: one package with features template (#2902)
*  NachoSoto: `Paywalls`: initial support for icons (#2882)
* NachoSoto: `Paywalls`: extracted intro eligibility out of templates
(#2901)
*  NachoSoto: `Paywalls`: changed `subtitle` to be optional (#2900)
* NachoSoto: `Paywalls`: added "features" to `LocalizedConfiguration`
(#2899)
* NachoSoto: `Paywalls`: fixed `{{ total_price_and_per_month }}` (#2881)
*  NachoSoto: `Paywalls`: updated template names (#2878)
*  NachoSoto: `Paywalls`: added accent colors (#2883)
* NachoSoto: `Paywalls`: changed images representation to an object
(#2875)
*  NachoSoto: `Paywalls`: added `offerName` parameter (#2877)
*  NachoSoto: `Paywalls`: new `{{ period }}` variable (#2876)
*  NachoSoto: `Paywalls`: disabled `PaywallViewMode`s for now (#2874)
* NachoSoto: `Paywalls`: added new `defaultPackage` configuration
(#2871)
*  NachoSoto: `Paywalls`: fixed tests on CI (#2872)
* NachoSoto: `Paywalls`: pre-fetch intro eligibility for paywalls
(#2860)
*  Andy Boedo: `Paywalls`: clean up the error view (#2873)
* NachoSoto: `Paywalls`: new API for easily displaying `PaywallView`
with just one line (#2869)
*  NachoSoto: `Paywalls`: handle missing paywalls gracefully (#2855)
* NachoSoto: `Paywalls`: temporarily disable non-fullscreen
`PaywallView`s (#2868)
* NachoSoto: `Paywalls`: added test to ensure package selection
maintains order (#2853)
* NachoSoto: `Paywalls`: added new `blurredBackgroundImage`
configuration (#2852)
*  NachoSoto: `Paywalls`: fuzzy `Locale` lookups (#2847)
*  NachoSoto: `Paywalls`: basic localization support (#2851)
*  NachoSoto: `Paywalls`: added `FooterView` (#2850)
*  NachoSoto: `Paywalls`: multi-package template (#2840)
*  NachoSoto: `Paywalls`: disable animations during unit tests (#2848)
* NachoSoto: `Paywalls`: `TrialOrIntroEligibilityChecker.eligibility(for
packages:)` (#2846)
* NachoSoto: `Paywalls`: added new `total_price_and_per_month` variable
(#2845)
*  NachoSoto: `Paywalls`: extracted `PurchaseButton` (#2839)
*  NachoSoto: `Paywalls`: extracted `IntroEligibilityStateView` (#2837)
* NachoSoto: `Paywalls`: support for multiple `PaywallViewMode`s (#2834)
* NachoSoto: `Paywalls`: add support for multiple images in template
configuration (#2832)
* NachoSoto: `Paywalls`: extracted configuration processing into a new
`TemplateViewConfiguration` (#2830)
* NachoSoto: `Paywalls`: improved support for dynamic type with
snapshots (#2827)
* NachoSoto: `Paywalls`: disable `macOS`/`macCatalyst`/`watchOS` for now
(#2821)
* NachoSoto: `Paywalls`: using new color information in template (#2823)
*  NachoSoto: `Paywalls`: set up CI tests and API Tester (#2816)
*  NachoSoto: `Paywalls`: added support for decoding colors (#2822)
* NachoSoto: `Paywalls`: ignore empty strings in
`LocalizedConfiguration` (#2818)
*  NachoSoto: `Paywalls`: updated `PaywallData` field names (#2817)
*  NachoSoto: `Paywalls`: added support for purchasing (#2812)
* NachoSoto: `Paywalls`: added tests for `PackageType` filtering (#2810)
* Andy Boedo: `Paywalls`: changed variable handling to use Swift `Regex`
(#2811)
*  NachoSoto: `Paywalls`: added `price` variable (#2809)
*  NachoSoto: `Paywalls`: determine intro eligibility (#2808)
*  NachoSoto: `Paywalls`: added header image to configuration (#2800)
*  NachoSoto: `Paywalls`: added `packages` to configuration (#2798)
* NachoSoto: `Paywalls`: add support for displaying
`StoreProductDiscount`s (#2796)
*  NachoSoto: `Paywalls`: added support for variables (#2793)
* NachoSoto: `Paywalls`: using `PaywallData` and setting up basic
template loading (#2781)
*  NachoSoto: `Paywalls`: initial configuration types (#2780)
*  NachoSoto: `Paywalls`: initial `RevenueCatUI` target setup (#2776)

</details>

### Other Changes

* `Debug`: add `Offering` metadata to debug screen (#3137) via NachoSoto
(@NachoSoto)
* `TestStoreProduct`: new `locale` parameter (#3134) via NachoSoto
(@NachoSoto)
* `Integration Tests`: fixed more flaky failures (#3218) via NachoSoto
(@NachoSoto)

---------

Co-authored-by: NachoSoto <ignaciosoto90@gmail.com>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants