In-app purchases and subscriptions made easy. Support for iOS, watchOS, tvOS, macOS, and visionOS.
MIT License
Bot releases are hidden (Show)
Published by revenuecat-ops over 2 years ago
This release is compatible with Xcode 14 beta 1
EntitlementInfo.isActive
returns true if requestDate == expirationDate
(#1684) via beylmk (@beylmk)seealso
(#1689) via NachoSoto (@NachoSoto)ROT13.string
thread-safety (#1686) via NachoSoto (@NachoSoto)PurchasesOrchestrator
: replaced calls to syncPurchases
with posting receipt for an individual product during SK2 purchases (#1666) via NachoSoto (@NachoSoto)Published by revenuecat-ops over 2 years ago
This release is compatible with Xcode 14 beta 1
EntitlementInfos
: added activeInAnyEnvironment
and activeInCurrentEnvironment
(#1647) via NachoSoto (@NachoSoto)In addition to EntitlementInfos.active
, two new methods are added to allow detecting entitlements from sandbox and production environments:
customerInfo.entitlements.activeInCurrentEnvironment
customerInfo.entitlements.activeInAnyEnvironment
MacDevice
: changed usage of kIOMasterPortDefault
to fix Catalyst compilation on Xcode 14 (#1676) via NachoSoto (@NachoSoto)Result.init(value:error:)
: avoid creating error if value is provided (#1672) via NachoSoto (@NachoSoto)Published by revenuecat-ops over 2 years ago
This version supports Xcode 14 beta 1
PurchasesOrchestrator.handleDeferredTransaction
: check NSError.domain
too (#1665) via NachoSoto (@NachoSoto)PurchasesOrchestrator
: replaced manual Lock
with Atomic
(#1664) via NachoSoto (@NachoSoto)CodableStrings.decoding_error
: added underlying error information (#1668) via NachoSoto (@NachoSoto)@available
properties (#1661) via NachoSoto (@NachoSoto)Published by revenuecat-ops over 2 years ago
Purchases.customerInfo()
: added overload with a new CacheFetchPolicy
(#1608) via NachoSoto (@NachoSoto)Storefront
: added sk1CurrentStorefront
for Objective-C (#1614) via NachoSoto (@NachoSoto)PurchasesOrchestrator
invoking listenForTransactions
only if SK2 is enabled (#1618) via NachoSoto (@NachoSoto)PurchasesOrchestrator
: removed lazy
hack for properties with @available
(#1596) via NachoSoto (@NachoSoto)PurchasesOrchestrator.purchase(sk2Product:promotionalOffer:)
: simplified implementation with new operator (#1602) via NachoSoto (@NachoSoto)Published by revenuecat-ops over 2 years ago
Configuration
object to configure the SDK with a cleaner syntax.Configuration
: Purchases.configure(
with: Configuration.Builder(withAPIKey: Constants.apiKey)
.with(usesStoreKit2IfAvailable: true)
.with(observerMode: false)
.with(appUserID: "<app_user_id>")
.build()
)
β οΈ The configure(withAPIKey:appUserID:)
method and its overloads have been deprecated in favor of using configure(with:)
and passing in a Configuration
.
X-Is-Sandbox
header in API requests (#1582) via NachoSoto (@NachoSoto)AmazonStore
to Store
enum (#1586) via Will Taylor (@fire-at-will)Configuration
object and API to configure Purchases (#1556) via Joshua Liebowitz (@taquitos)shouldShowPriceConsent
on PurchasesDelegate
(#1520) via Joshua Liebowitz (@taquitos)ManageSubscriptionsHelper
: fixed discrepancy between SystemInfo.isAppleSubscription(managementURL:)
and SystemInfo.appleSubscriptionsURL
(#1607) via NachoSoto (@NachoSoto)PurchasesOrchestrator
: don't listen for StoreKit 2 transactions if it's disabled (#1593) via NachoSoto (@NachoSoto)RawDataContainer
includes all data (#1565) via NachoSoto (@NachoSoto)DeferredPromotionalPurchaseBlock
(#1600) via NachoSoto (@NachoSoto)StoreKit 2
purchases: don't throw when purchase is cancelled (#1603) via NachoSoto (@NachoSoto)SubscriptionPeriod
s are represented as 1week instead of 7days (#1591) via Will Taylor (@fire-at-will)PurchaseStrings
: fixed transaction message formatting (#1571) via NachoSoto (@NachoSoto)willRenew
update comment for lifetime will be false (#1579) via Josh Holtz (@joshdholtz)SK1StoreProductDiscount
: handle SKProductDiscount.priceLocale
being nil
and created StoreKitWorkarounds
(#1545) via NachoSoto (@NachoSoto)ErrorUtils.logDecodingError
(#1539) via NachoSoto (@NachoSoto)GetIntroEligibilityOperation
: replaced response parsing with Decodable
(#1576) via NachoSoto (@NachoSoto)PostOfferForSigningOperation
: changed response parsing to using Decodable
(#1573) via NachoSoto (@NachoSoto)CustomerInfo
and related types to use Codable
(#1496) via NachoSoto (@NachoSoto)MagicWeatherSwiftUI
: fixed usage of PurchaseDelegate
(#1601) via NachoSoto (@NachoSoto)PeriodType
/PurchaseOwnershipType
/Store
(#1558) via NachoSoto (@NachoSoto)StoreTransaction
(#1584) via aboedo (@aboedo)Purchases.canMakePayments
: moved implementation to StoreKitWrapper
(#1580) via NachoSoto (@NachoSoto)BackendGetIntroEligibilityTests
: fixed test that was passing before anything ran (#1575) via NachoSoto (@NachoSoto)PeriodType
/PurchaseOwnershipType
/Store
: conform to Encodable
(#1551) via NachoSoto (@NachoSoto)EntitlementInfosTests
(#1547) via NachoSoto (@NachoSoto)ProductRequestData
: added Storefront
for receipt posting (#1505) via NachoSoto (@NachoSoto)RawDataContainer
conformances to APITesters (#1550) via NachoSoto (@NachoSoto)EntitlementInfo.isEqual
(#1548) via NachoSoto (@NachoSoto)CustomerInfo
: moved deprecated property to Deprecations
(#1549) via NachoSoto (@NachoSoto)PackageType
: simplified typesByDescription
and implemented CustomDebugStringConvertible
(#1531) via NachoSoto (@NachoSoto)Published by revenuecat-ops over 2 years ago
Purchases
pod in favor of RevenueCat
Published by revenuecat-ops over 2 years ago
Storefront
type to abstract SK1's SKStorefront
and SK2's StoreKit.Storefront
.Storefront.currentStorefront
.ErrorCode.offlineConnectionError
to differenciate offline errors versus the more generic .networkError
.Purchases.setFirebaseAppInstanceID
to allow associating RevenueCat users with Firebase.Purchases.setPushTokenString
as an overload to Purchases.setPushToken
.PurchasesDelegate.purchases(_:shouldPurchasePromoProduct:defermentBlock:)
to PurchasesDelegate.purchases(_ purchases: Purchases, readyForPromotedProduct product: StoreProduct, purchase:)
to clarify its usage (see #1460).Published by revenuecat-ops over 2 years ago
Added new method setMixpanelDistinctID
as a convenience method for setting the required attribute for the Mixpanel integration #1397
getPromotionalOffer
has been deprecated in favor of promotionalOffer
#1405
getEligiblePromotionalOffers
has been deprecated in favor of eligiblePromotionalOffers
#1405
StoreProductDiscount
now includes the numberOfPeriods
property #1428
Added workaround for StoreKit 1 incorrectly reporting purchase cancellations #1450
MagicWeatherSwiftUI now includes an example for using purchases(:shouldPurchasePromoProduct:defermentBlock:)
#1459
Various documentation improvements
Additional under-the-hood improvements, continuing to focus on network requests and tests.
Published by revenuecat-ops over 2 years ago
Added new method setMixpanelDistinctID
as a convenience method for setting the required attribute for the Mixpanel integration #1397
getPromotionalOffer
has been deprecated in favor of promotionalOffer
#1405
getEligiblePromotionalOffers
has been deprecated in favor of eligiblePromotionalOffers
#1405
StoreProductDiscount
now includes the numberOfPeriods
property #1428
Added workaround for StoreKit 1 incorrectly reporting purchase cancellations #1450
MagicWeatherSwiftUI now includes an example for using purchases(:shouldPurchasePromoProduct:defermentBlock:)
#1459
Various documentation improvements
Additional under-the-hood improvements, continuing to focus on network requests and tests.
Published by revenuecat-ops over 2 years ago
Added new method checkTrialOrIntroDiscountEligibility(product:)
, which allows you to check for intro or discount eligibility for a single StoreProduct
.
https://github.com/RevenueCat/purchases-ios/pull/1354
Added explicit parameter name for checkTrialOrIntroDiscountEligibility(productIdentifiers:)
.
The existing method without the parameter name still work, but is now deprecated. Xcode will offer an auto fix-it for it.
https://github.com/RevenueCat/purchases-ios/pull/1362
Made StoreProduct
initializers public so they can be used for testing.
Added auto-fix-it for invalidatePurchaserInfoCache
rename
https://github.com/RevenueCat/purchases-ios/pull/1379
Docs improvements
A lot of under-the-hood improvements, mainly focusing on network requests and tests.
Published by revenuecat-ops over 2 years ago
RevenueCat iOS SDK v4 is here!!
There have been a lot of changes since v3!
Here are the highlights:
New async / await
alternatives for all APIs that have completion blocks, as well as an AsyncStream
for CustomerInfo.
New types that wrap StoreKit's native types, and we cleaned up the naming of other types and methods for a more consistent experience.
You can now use showManageSubscriptions()
and beginRefundRequest()
to help your users manage their subscriptions right from the app.
We rewrote the SDK in 100% Swift. This made the code more uniform and easy to maintain, and helps us better support StoreKit 2.
[Experimental] Introduced support for using StoreKit 2 under the hood for compatible devices. This is currently in beta phase, and disabled by default.
When enabled, StoreKit 2 APIs will be used under the hood for purchases in compatible devices. You can enable this by configuring the SDK passing useStoreKit2IfAvailable: true
.
On devices that don't support StoreKit 2, StoreKit 1 will be used automatically instead.
We built a new Documentation site with Docc with cleaner and more detailed docs.
The new documentation can be found here.
Published by revenuecat-ops over 2 years ago
RC 4 introduces the following updates:
checkPromotionalDiscountEligibility
with getPromotionalOffer
, which returns a PromotionalOffer
.Purchases/purchase(package:discount:)
and its variants to Purchases/purchase(package:promotionalOffer:)
. They now take a PromotionalOffer
instead of a StoreProductDiscount
.StoreProduct.price
and StoreProductDiscount.price
from NSDecimal
to the much more useful NSDecimalNumber
.StoreProduct.ProductType
, and StoreProduct.ProductCategory
, which provide extra information about whether a product is a consumable, non-consumable, auto-renewable or non-auto-renewable subscription.currencyCode
to StoreProduct
and StoreProductDiscount
.localizedPriceString
to StoreProductDiscount
.These changes add to all of the changes from beta RC 2, listed here.
Published by revenuecat-ops over 2 years ago
RC 3 introduces the following updates:
setCleverTapID
, for integration with CleverTap..noIntroOfferExists
as an IntroEligibilityStatus
, for more granularity when checking for intro pricing eligibility.StoreProductDiscount.type
, which allows you to easily tell whether a discount represents a Promo Offer or an Intro Pricing.These changes add to all of the changes from beta RC 2, listed here.
Published by aboedo over 2 years ago
checkTrialOrIntroductoryPriceEligibility
might refresh the receipt if it's not present on device,Published by revenuecat-ops over 2 years ago
RC 2 introduces the following updates:
SubscriptionPeriod.Unit.unknown
. Subscriptions with empty SubscriptionPeriod
values will have nil
subscriptionPeriod
instead.StoreProductDiscount.none
, since it wasn't needed.useStoreKit2IfAvailable
(Experimental) configuration option. This is disabled by default.These changes add to all of the changes from beta RC 1, listed here.
Published by revenuecat-ops over 2 years ago
RC 1 introduces the following updates:
Purchases.paymentDiscount(forProductDiscount:product:completion:)
and Purchases.paymentDiscount(forProductDiscount:product:)
have been removed. Now, instead of obtaining the SKPaymentDiscount
from a SKProductDiscount
to then call purchase(package:discount:)
, you check eligibility for the promo offer by calling checkPromotionalDiscountEligibility(forProductDiscount:product:)
, then get the StoreProductDiscount
directly from the StoreProduct
and pass that into purchase(package:discount:)
.
StoreProduct
and StoreProductDiscount
, replace SKProduct
and SKProductDiscount
in the following methods:
Purchases.getProducts(_:completion:)
Purchases.products(_:)
Purchases.purchase(product:completion:)
Purchases.purchase(product:)
Purchases.purchase(product:discount:completion:)
Purchases.purchase(product:discount:)
Purchases.purchase(package:discount:completion:)
Purchases.purchase(package:discount:)
PurchasesDelegate.purchases(shouldPurchasePromoProduct:defermentBlock:)
StoreProduct.introductoryPrice
has been renamed to StoreProduct.introductoryDiscount
StoreTransaction
now includes quantity
Renamed Purchases.restoreTransactions
to Purchases.restorePurchases
Lowered StoreProduct.introductoryDiscount
availability to iOS 11.2 and equivalent OS versions
Added several @available
annotations for automatic migration from StoreKit types
In addition to all of the changes from beta 10, listed here.
Published by vegaro over 2 years ago
Published by revenuecat-ops almost 3 years ago
.xcframework
not including dSYMsPublished by revenuecat-ops almost 3 years ago
Beta 10 introduces the following updates:
StoreTransaction
, replaces SKPaymentTransaction
in the return types of the following methods:
Purchases.purchase(product:completion:)
Purchases.purchase(package:completion:)
Purchases.purchase(package:discount:completion:)
Purchases.purchase(package:discount:completion:)
PurchasesDelegate.purchases(shouldPurchasePromoProduct:defermentBlock:)
CustomerInfo.nonSubscriptionTransactions
StoreProduct.PromotionalOffer
has been renamed to StoreProduct.StoreProductDiscount
.In addition to all of the changes from beta 9, listed here.
Published by revenuecat-ops almost 3 years ago
identify
, previously deprecated, has been removed in favor of logIn
.reset
, previously deprecated, has been removed in favor of logOut
.Package.product
has been replaced with Package.storeProduct
. This is an abstraction of StoreKit 1's SKProduct
and StoreKit 2's StoreKit.Product
, but it also adds useful features like pricePerMonth
and priceFormatter
. The underlying objects from StoreKit are available through StoreProduct.sk1Product
and StoreProduct.sk2Product
.purchases-ios
v4 requires using Xcode 13.2 or newer.
It also updates the minimum deployment targets for iOS, macOS and tvOS.
v3 | v4 | |
---|---|---|
iOS | 9.0 | 11.0 |
tvOS | 9.0 | 11.0 |
macOS | 10.12 | 10.13 |
watchOS | 6.2 | 6.2 (unchanged) |
showManageSuscriptions(completion:)
beginRefundRequest(forProduct:)
beginRefundRequest(forEntitlement:)
.beginRefundRequestForActiveEntitlement()
checkTrialOrIntroductoryPriceEligibility(productIdentifiers:completion:)
now uses StoreKit 2 if it's available, to make calculation more accurate and fast.setup
, useStoreKit2IfAvailable
(defaults to false
), to use StoreKit 2 APIs for purchases instead of StoreKit 1.Async
/ Await
alternative APIsAsync
/ Await
alternative APIs were made available through Xcode's auto-generation for Objective-C projects. This beta re-adds the Async
/ Await
alternative APIs for v4.showManageSuscriptions(completion:)
: Use this method to show the subscription management for the current user. Depending on where they made the purchase and their OS version, this might take them to the managementURL
, or open the iOS Subscription Management page.beginRefundRequestForCurrentEntitlement
: Use this method to begin a refund request for the purchase that granted the current entitlement.beginRefundRequest(forProduct:)
: Use this method to begin a refund request for a purchase, specifying the product identifier.beginRefundRequest(forEntitlement:)
: Use this method to begin a refund request for a purchase, specifying the entitlement identifier.useStoreKit2IfAvailable
parameter to setup
(defaults to false
). If enabled, purchases will be done by using StoreKit 2 APIs instead of StoreKit 1. This is currently experimental, and not all features are supported with StoreKit 2 APIs.verboseLogHandler
or verboseLogs
to enable more details in logs, including file names, line numbers and method names.useStoreKit2IfAvailable
in setup
or set it to false
.