In-app purchases in SwiftUI

Photo by Pixabay on

How do you implement in-app purchases with SwiftUI?

It’s interesting how little information there is out there on how to integrate in-app purchases with SwiftUI. Even the developer demo from Apple is based on using UIKit. Hopefully you find this useful from my experience.

Here’s a snippet of code that handles the return of products to an in-app purchases view in SwiftUI. It is triggered by the purchased variable returning false prompting the user with a purchases view in order to progress.

This code is assuming you have already implemented IAP Manager in the same way you would for UIKit.

In-app purchases view

struct IAPView: View {
    var iap = IAPManager.shared
    @Binding var purchased: Bool
    @ObservedObject var productsStore: ProductsStore =
    var body: some View {
        VStack (alignment: .leading) {
              ForEach (productsStore.getAvailableProductData(),
                         id: \.self) { product in
                    Button(action: {
                     HStack {
                        VStack (alignment: .leading) {
// Show the product's price in the local 
//currency returned by the App Store.
                          product) ?? Messages.priceUnavailable))
                        ButtonView(text: AppText.buyButtonTitle,
                         gameColor: AppNumbers.navyBlue)                                

The Product Store

 import SwiftUI
 import StoreKit
 final class ProductsStore: ObservableObject, Identifiable {
     static let shared = ProductsStore()
     @Published var data = [SectionElement]()
     @Published var purchases = [String]()
         willSet {
           DispatchQueue.main.async {
     /// If there are available products, return them.
     func getAvailableProductData() -> [SKProduct] {
         for section in {
             if section.type == .availableProducts,
                let content = section.elements as? [SKProduct] {
                 return content
         return [SKProduct]()
     ///returns true if the user has already purchased the resource
     func checkExistingPurchases(resourceFile: ProductIdentifiers) 
-> Bool {
         for identifier in resourceFile.identifiers! {
             for item in purchases {
                 if identifier == item {
                     return true
         return false

 /// A structure that is used to represent a list of products or
 struct SectionElement {
     /// Products/Purchases are organized by category.
     var type: SectionType
     /// List of products/purchases.
     var elements = [Any]()

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: