* tests: have `JSONEncoder` of snapshot tests be a copy of the encoder user in the SDK
* tests: update the dates in the `CustomerInfo` snapshots for decoding tests to have ISO 8601 format
* update variable comment
* fix lint
* feat: add `hasPaywall` getter to `Offering`
Returns `true` if the offering has either a v1 or a v2 paywall
* docs: update some methods references changing `PaywallData` with "paywall", as `PaywallData` only refers to v1 paywalls
* docs: improve reference of `Offering`'s `paywall` and `paywallComponents` to mention the new `hasPaywall` property
* lint
* tests: add unit tests that check the `hasPaywall` property of `Offering`
* api tests: add `paywallComponents` and `hasPaywall` to SwiftAPITester
* feat: add support for presenting draft paywalls under `@_spi(Internal)` attribute
* fix: initialize `useDraftPaywall` property of `PaywallView`
* feat: have `PaywallView` actually show draft paywall when `useDraftPaywall` is `true`
* remove lint warning
* silence linter warning
* tests: add unit tests for `paywallComponents` and `draftPaywallComponents` in `OfferingsResponse`
* tests: move test offerings with v2 paywalls into a new file not to affect existing decode + encode test
* remove unnecessary property wrapper
* silence lint warning
* We can't just remove PAYWALL_COMPONENT because we don't support macos and tv and things were failing
* Move PartialComponent outside of PaywallComponent extension
* Fix some lint errors
* Wrong thing
* Undid things i shouldn't have done
* Removed more
* Added comment
* Removed/fix some places for the check thingies
* RevenueCat module compiles on all the things
* RevenueCatUI compiles in all the platforms now
* Make all the things compile again
* Make work for visionOS
* Fix some platform and xcode version issues
* Fix failing spm ios 15 test
* Undo circleci changes
* Replace smooth with easeInOut
* Only run the thing i want
* Attempt to remove circular
* Explicit returns
* Does this pass
* This is it
* Swift 5.9 for this
* All tests again
* Undid public testing processor stuff
* Undo this too
* Swift compiler check out pill style circular
* Fixes from PR review
* Fix compile for mac
* Added tests
* Removed compiler flags because extra work to handle this on CI unit tests when we are releasing this soon and this isn't really that dangerous
* Fix lint
* Some naming improvements
* Passing UIConfig into Offering
* Reorged some data structures
* Fixed some lint
* This
<!-- Thank you for contributing to Purchases! Before pressing the
"Create Pull Request" button, please provide the following: -->
### Checklist
- [ ] If applicable, unit tests
- [ ] If applicable, create follow-up issues for `purchases-android` and
hybrids
### Motivation
<!-- Why is this change required? What problem does it solve? -->
<!-- Please link to issues following this format: Resolves#999999 -->
### Description
This adds the `backend_error_code` property to diagnostics
`http_request_performed` events.
### Motivation
Template 5 but with multiple tiers 😊
### Description
Enabling Template 7 by changing `7_disabled` to `7`
- Changed a `header.jpg` to `header.heic` to try and fix issue with
weirdly failing snapshot UI test
- Changed visibility on `TestData` from `public` to `internal`
- Hides tier selector if only one tier
- Changed `color_overrides_by_tier` to `colors_by_tier` and
`image_overrides_by_tier` to `images_by_tier`
- The original implementation was going to default to existing color and
images configurations and then override by tier
- However, this turned out to be harder to implement on the
configuration side
- `Colors` got four new optional values
- `tier_control_background`
- `tier_control_foreground`
- `tier_control_selected_background`
- `tier_control_selected_foreground`
### Demo
#### Full Screen
https://github.com/RevenueCat/purchases-ios/assets/401294/e5317a53-428c-415e-a1a1-b4231d32a776
### Footer
https://github.com/RevenueCat/purchases-ios/assets/401294/8905b55e-0fa2-49f0-aa1c-d4c1e694fb5b
### Footer Condensed
https://github.com/RevenueCat/purchases-ios/assets/401294/311d78fb-bdeb-43cd-b601-9c60a8a54b6f
**This is an automatic release.**
### New Features
* Paywalls with custom purchase and restore logic handlers (#3973) via
James Borthwick (@jamesrb1)
### Bugfixes
* Prevent paywall PurchaseHandler from being cleared on rerender (#4035)
via Josh Holtz (@joshdholtz)
* Update Purchase Tester for 5.0.0 (#4015) via Will Taylor
(@fire-at-will)
### Dependency Updates
* Bump fastlane from 2.221.0 to 2.221.1 (#3977) via dependabot[bot]
(@dependabot[bot])
### Other Changes
* Bring official `xcodes` back to CI (#4029) via Cesar de la Vega
(@vegaro)
* Paywalls tester with sandbox purchases (#4024) via James Borthwick
(@jamesrb1)
* Update v5 migration guide to contain current latest version (#4019)
via Toni Rico (@tonidero)
* CI Build Docs Improvements (#4014) via Will Taylor (@fire-at-will)
* Use available resource class for backend-integration-tests-offline-job
(#4013) via Will Taylor (@fire-at-will)
* Add `X-Preferred-Locales` header (#4008) via Cesar de la Vega
(@vegaro)
---------
Co-authored-by: Toni Rico <antonio.rico.diez@revenuecat.com>
Co-authored-by: Josh Holtz <me@joshholtz.com>
`RemoteImage` now uses two images: a high res image (as before), and a
new low res image which will be used if it is available before the high
res image has been loaded.
To enable this, it now uses two `ImageLoader` instances, one for to
fetch the low res image, a second for high res image.
It assumes that the low res image url is the same as the high res image
url, with a suffix appended (default `_low_res`) to the file name, eg
`/images/myImage.jpg` is assumed to have a low res equivalent at
`/images/myImage_low_res.jpg`.
It requests the high and low res images concurrently, and displays an
error when both requests fail. A low res image will never replace a high
res image even if it is received last.
Here is a video of it loading a "low res" image, following by high res
image. For this video the low-res image was intentionally set to a
completely different image to make the change easy to see. If you move
the slider manually you can control the speed.
https://github.com/RevenueCat/purchases-ios/assets/109382862/97521803-5c12-43d0-92a8-596b23cdcff6
---------
Co-authored-by: Josh Holtz <me@joshholtz.com>
### Description
This adds a new diagnostics event `http_request_performed` with some
useful information we would like to track about the http requests
performed to our servers.
### Motivation
Get more context with targeting information
### Description
- Parse targeting information into `Offerings`
- Add targeting context into `Offerings.current`
- Add targeting context into `getCurrentOffering(forPlacement: String)`
- Post targeting context in post receipts
---------
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
### Motivation
New function to get `Offering` by a placement identifier
### Description
New `currentOffering(forPlacement: String): Offering?` method on
`Offerings`
- Added demo button for this in purchase tester app
```swift
// Example usage
if let offering = offerings.currentOffering(forPlacement: "onboarding") {
showPaywall(offering)
}
```
#### Logic flow
- If a placement identifier explicitly exists within the
`placements.offeringIdsByPlacement` dictionary, the method attempts to
fetch the corresponding `Offering` without resorting to a fallback
- Example: when there is a `nil` / null value for a placement, we don't
want to use the fallback
- If the placement identifier does not exist, the method then attempts
to fetch a fallback offering defined by `placements.fallbackOfferingId`
#### New placements object in offerings response
```js
{
// other offerings stuff
"placements": {
"fallback_offering_id": "offering_a", // can be null
"offering_ids_by_placement": {
"onboarding_start": null,
"onboarding_end": "offering_b",
}
}
}
```
---------
Co-authored-by: Guido Torres <guido@revenuecat.com>
Co-authored-by: Josh Holtz <me@joshholtz.com>
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>