Repository navigation
PurchaseKit 4.0 covers what StoreKit 2 reports about subscriptions, offers and transactions, and makes the
kit's own types extensible, so a value Apple adds later is no longer a breaking release.
Upgrading from 3.x? Read Migrating to PurchaseKit 4. It shows every break below with before-and-after code.
What broke, and why
ProductTypeandPurchasesErrorare structs, not enums. As enums, every value StoreKit added was a
breaking release: OS 27's subscription bundles and suites would have been one. Now they are
RawRepresentablestructs, the pattern StoreKit itself uses. Aswitchover them needs adefaultbranch.ProductType.unknownis gone. A product kind with no constant in this build arrives as itself, with
StoreKit's raw value..unknownwas only ever a guess.PurchasesErrorfollows theURLErrorlayout: acode, plusproductID,offerIDand the
underlyingErrorit was translated from. Writecatch PurchasesError.purchaseCancelled { … }or
error.code == .purchasePending.
- StoreKit errors are translated. In 3.x,
StoreKitErrorandProduct.PurchaseErrorescaped raw. They now
arrive as codes such asproductUnavailable,ineligibleForOffer,invalidOffer,networkUnavailableor
notAvailableInStorefront. A cancellation reported as an error ispurchaseCancelled, the same as a cancelled
sheet. - Protocol requirements changed, so mocks need updating.
PurchasesProtocolnow requires
purchase(productID:options:),subscriptionStatuses(inGroup:),isEligibleForIntroOffer(inGroup:)and
appPurchaseInfo().purchase(productID:)andpurchase(productID:appAccountToken:)became extension
conveniences over the options-based call, so a stand-in implements one purchase method instead of two. - Model initializers:
StoreProductrequirescurrencyCode, andStoreTransactionrequiresproductType. activeSubscriptions()includes subscription bundles and suites. Comparing againstautoRenewablealone
made a bundle subscriber look unsubscribed.
New
- Subscription status:
subscriptionStatus(inGroup:)/subscriptionStatuses(inGroup:)and the live
subscriptionStatusUpdatesstream.StoreSubscriptionStatuscarries the state (subscribed, grace period,
billing retry, expired, revoked), renewal date, auto-renew product, grace-period end, expiration reason and
isActive. PurchaseOptions: quantity, promotional offers signed as JWS, win-back offers, the intro-eligibility JWS and
Ask to Buy simulation, alongsideappAccountToken. An unknown win-back offer fails withofferNotFoundbefore
the sheet appears, instead of charging full price.- Richer models:
StoreProductgains currency, subscription period and introductory, promotional and
win-back offers.StoreTransactiongains product type, ownership (family sharing), environment, reason, offer,
revocation reason and type, billing plan, storefront and price. appPurchaseInfo()returns the original app version, for apps moving from paid to free with purchases.
currentStorefrontCountryCode()andunavailableProductIDsare new as well.- App Store sheets on iOS, Mac Catalyst and visionOS: manage subscriptions, refund request, offer-code
redemption.
Fixed
- An uncached
requestProductsno longer re-announces owned products as new purchases. - Products missing from the cache are fetched in one request instead of one request per entitlement.
hasEntitlement(for:)asks StoreKit about the one product instead of walking every entitlement.
Distribution
- The library no longer forces static linking, so Xcode picks static or dynamic linking per client.
- The package is set up for Swift Package Index, which will host the documentation.
Two names carry a Store prefix, StoreSubscriptionStatus and StoreSubscriptionPeriod, because StoreKit
declares top-level typealiases with the plain names. Any file importing both modules would otherwise fail
with "ambiguous for type lookup".
Requires Xcode 26 or later. Deploys to iOS, iPadOS, Mac Catalyst, macOS, tvOS, watchOS and visionOS 26.