* feat: have testing apps take RevenueCat API key and Proxy URL from local.xcconfig file
* fix wording mistakes in `Local.xcconfig.SAMPLE`
* chore: include `ConfigItem.swift` file in `verify_no_included_apikeys` check
* fix more mistakes in comments
* Introduce PurchaseParams to allow passing extra configuration info when making a purchase
* simplify naming
* fallback to old method when flag is not enabled
* Add $(inherited) to the test targets so they pick up compiler flags from Local.xcconfig
* Include product/package inside PurchaseParams
* fix tests
* add compiler flag check
* update purchase tester
* fix docs
* add tests
* Update Sources/Networking/Operations/PostReceiptDataOperation.swift
Co-authored-by: Toni Rico <toni.rico.diez@revenuecat.com>
---------
Co-authored-by: Toni Rico <toni.rico.diez@revenuecat.com>
* replace withCheckedThrowingContinuation calls with withUnsafeThrowingContinuation
* replaced instances of withCheckedContinuation -> withUnsafeContinuation
* update the links in comments to point to the issue not the PR
* linting
---------
Co-authored-by: andy boedo <andresboedo@gmail.com>
### Description
This adds a new API `setKochavaDeviceId` that allows to set the kochava
device ID required for the Kochava integration.
Keeping on hold until backend support is added
## More project structure cleanup:
- Removes redundant workspace and project files for PurchaseTester
- Cleans up bad references
- Cleans up certificates
- Re-does the process to deploy PurchaseTester, since it was designed to
run from the xcworkspace, which doesn't work anymore.
- adds a `dry-run` option to deploying PurchaseTester and adds a job for
it in the all-tests workflow. It tries building it and archiving but
doesn't actually publish to TestFlight. We didn't really have a test for
this, so it's another thing that could have broken in production.
## Motivation
Having to remember which Xcode project to open to work on every specific
feature drives me insane.
This just adds the Testing Apps to the main RevenueCat.workspace so we
can launch them from there and I can stop pulling my hair out.
It also removes the old UIKit PurchaseTester since we haven't been using
it for years.
The Backend Integration tests app and the PurchaseTesterSwiftUI app were
using a storekit config file from the old PurchaseTester for some
reason, so I cleaned that up too - added it as a separate file per app.
| Before | After |
| :-: | :-: |
| <img width="312" alt="Screenshot 2024-07-24 at 5 54 55 PM"
src="https://github.com/user-attachments/assets/3afc73b1-3432-4ec0-843c-b9ccfdd371ce">
| <img width="325" alt="image"
src="https://github.com/user-attachments/assets/f5ce7d06-4adc-40d5-a086-73febc0d84cf">
|
# Changes summary:
- Add all Testing Apps to `RevenueCat.xcworkspace`
- Kill PurchaseTester UIKit
- Move StoreKit config file from PurchaseTester UIKit to
BackendIntegrationTests
- Create new StoreKit Config file for PurchaseTester SwiftUI
- Replace SPM dependency from PurchaseTester -> RevenueCat with a local
dependency
### Motivation
Adding new method to manually sync attributes and fetch fresh offerings
### Description
- New `Purchases.shared.syncAttributesAndOfferingsIfNeeded()` method
- Syncs subscriber attributes and then fetches fresh offerings from
network
- This is designed to be a blocking call since developer will want fresh
offerings after syncing subscriber attributes
- The method is rate limited to 5 calls per minute (new `RateLimiter`
class()
---------
Co-authored-by: Josh Holtz <me@joshholtz.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>
Receipts in logs have extra escape sequences now (forward slashes), so
this updates the ReceiptInspector tool to be able to accept them for
easier usage.
It also accepts extra `"` so that if you copied slightly incorrectly it
still works.
Checking for the presence of `Xcode/DerivedData` in the receipt path was
failing for TestFlight builds or if the .app bundle generated by Xcode
was moved from the folder.
Additionally, checking for `MASReceipt/receipt` seems less robust than
simply using compiler directives.
Instead, for macOS apps, we check the environment embedded in the receipt and alternatively check the signature of the app bundle.
---------
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
Apple changed `xrOS` to `visionOS` on the latest beta. Looks like this
was already supported in prior `Xcode 15.1` betas, so this doesn't break
compatibility with them.
### Context:
`#if os(iOS)` no longer evaluates to `true` when compiling for
`visionOS`
Which means we need `|| os(xrOS)`.
But to support older Xcode we need `#if swift(>=5.9) && os(xrOS)`.
But, fun fact, short-circuiting doesn’t work in `Xcode 13`.
And we still need that to run iOS <15 tests (`FB12223404` /
`FB12805891`)
💩
This works around that by defining our own `VISION_OS` flag.
### Changes:
- Added `VISION_OS` compile time flag to determine SDK
- Replaced `#if os(xrOS)` with `#if VISION_OS`
- Added flag to `Package.swift` (thanks @neonichu for helping with this)
### Description
While uploading purchase tester to testflight, we were getting these
errors:
```
[Application Loader Error Output]: ERROR: [ContentDelivery.Uploader] Asset validation failed (90396) Invalid Icon. The watch application 'PurchaseTester.app/Watch/PurchaseTesterWatchOS.app' contains an icon file 'Icon Image-AppIcon-watch-1024x1024@1x.png' with an alpha channel. Icons should not have an alpha channel.
[Application Loader Error Output]: ERROR: [ContentDelivery.Uploader] Asset validation failed (90717) Invalid App Store Icon. The App Store Icon in the asset catalog in 'PurchaseTester.app/Watch/PurchaseTesterWatchOS.app' can't be transparent nor contain an alpha channel.
```
This icon was added in #2701. After trying it manually, removing the
alpha channel seems to have worked in fixing the issue while uploading.
This PR just changes that icon with a version without an alpha channel.
Depends on #2326 and #2328.
This allows us to keep all the code, except users won't be able to
configure the SDK with this option.
Note that `Signing.ResponseVerificationMode.enforced` _is_ available, so
we can still test all that behavior, including from integration tests.
See #2211.
If `restorePurchases` fails for any reason, we still want to try to load
the local receipt. We're only interested in refreshing the receipt to
load it.