Welcome to StoreKitPro!

⚠️ Important!
Privacy Policy Link, User Agreement Link, and Restore Purchases button are all now REQUIRED to be in the binary build for an app to get approved.

Setup


1. Download the Resources. Drag and drop the StoreKitPro folder into your Xcode project



2. Configure StoreKitPro

Add 
StoreKitPro.configure()
in the init() of your App (if your app is SwiftUI based) or in the applicationDidFinishLaunching(with options:) (if your app is UIKit based)

3. Set up your Products.storekit file (for testing purposes)

⚠️ Auto-renewable Subscriptions: Does not support Promotional Offers (will be available as soon as StoreKit eliminates the need to set up a server for promotional offers validation)


4. Set the StoreKit Configuration (for testing purposes)



5. Configure your ids in App Store Connect (for the App Store)

Setting up a Products.storekit file is great for testing your implementation. However ultimately you will need to set up your ids in App Store Connect.
Follow this link for how to set up your ids: https://developer.apple.com/in-app-purchase/
Go to 'Set up in App Store Connect'


6. Add your product ids to the StoreKitProSetup.swift file



StoreKitPro actions


Fetch products
let products = try await StoreKitPro.retrieveProducts(productIds: StoreKitProSetup.productIds)

Restore purchases
try await StoreKitPro.restorePurchases()

Show Manage Subscriptions Sheet (iOS only)
try await StoreKitPro.showManageSubscriptions()

Show Refund Sheet (iOS only) / Go to Refund Page (macOS only)
try await StoreKitPro.beginRefundProcess(for: product)

Show Redeem an Offer Code Sheet (iOS16+ only)
try await StoreKitPro.showOfferCodeRedeemSheet()

Product extension


The functionalities described below are set on the Product struct form Apple's StoreKit.  

Purchase a product
try await product.buy()

Purchase a consumable product that is of a certain type (ex. coin)
try await product.buy(customConsumableId: "coin")

Purchase a consumable product that has several consumable items (ex. 10 coins)
try await product.buy(multiplier: 10, customConsumableId: "coin")

Purchase a consumable with a quantity option (buys several instances of that consumable)
try await product.buy(quantity: 5)

Get the consumable count for a consumable product
let consumableCount = product.consumableCount()

Get the consumable count for a consumable product of a certain type (ex. coin)
consumableCount = product.consumableCount(for: "coin")

Consume a consumable product
product.consume()

Consume multiple consumable products at once
product.consume(amount: 5, consumableId: "coin")

Consume multiple consumable products of a certain type at once
product.consume(amount: 5, consumableId: "coin")
 
Consume a consumable product of a certain type (ex. coin)
product.consume(consumableId: "coin")

Consume a consumable product of a certain type (ex. coin) and get the current consumable count
if product.consume(consumableId: "coin") {
    consumableCount = product.consumableCount(for: "coin")
}

Reset all consumable counts (DEBUG only)
try await StoreKitPro.resetConsumable(customId: "coin")

Check if product has been purchased (for all product types)
let hasBeenPurchased = try await product.hasBeenPurchased

Check product's subscription state (for only subscription types)
let subscriptionState = try await product.subscriptionState

Get product's subscription state description (for only subscription types)
let subscriptionStateDescription = try await product.subscriptionStateDescription

Get product's subscription renewal period description (for only subscription types)
let subscriptionRenewalPeriodDescription = try await product.subscriptionRenewalPeriodDescription

Get product's subscription renews at description (for only subscription types)
let renewsAtDescription = try await product.renewsAtDescription

Get product's subscription renews in description (for only subscription types)
let renewsInDescription = try await product.renewsInDescription

Check if product's group has active subscription (for only subscription types)
let hasActiveSubscription = try await product.hasActiveSubscription

Check if product has active purchase (for only non-subscription types)
let hasActivePurchase = try await product.hasActivePurchase

Get product's introductory offer payment mode (returns an optional)
let introductoryOfferPaymentMode = try await product.introductoryOfferPaymentMode

Get product's introductory offer display description
let introductoryOfferDisplayDescription = try await product.introductoryOfferDisplayDescription

Get product's introductory offer (returns an optional)
let introductoryOffer = try await product.introductoryOffer

Is product eligible for intro offer
let isEligibleForIntroOffer = await product.isEligibleForIntroOffer

Does the product have an intro offer
let hasIntroOffer = await product.hasIntroOffer

Is product a subscription
let isSubscription = product.isSubscription

Is product a consumable
let isConsumable = product.isConsumable

Note: the products are of type Product from StoreKit. All the Product properties (like 'displayName' or 'displayPrice') can be accessed 🚀

Demo project


Check out the Demo SwiftUI project 🌟