I can't get StoreKit to work and I don't know how to debug it

I'm completely lost with StoreKit. I just want to add a button that people can click on and pay a small fee and that's it. Nothing else. I've tried looking at the StoreKit sample code here: https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api

The sample code doesn't explain how to actually take the code apart and implement it in a simple way. How can you have one single product that you can buy by pressing a button?

Here is my code in Store.swift.

import Foundation

import StoreKit



typealias Transaction = StoreKit.Transaction



public enum StoreError: Error {

    case failedVerification

}



class Store: ObservableObject {

    

    @Published var products: [Product] = []

    @Published var purchasedProducts: [Product] = []

    

    let productList: [String: String]



    init() {

        if let path = Bundle.main.path(forResource: "Products", ofType: "plist"),

        let plist = FileManager.default.contents(atPath: path) {

            productList = (try? PropertyListSerialization.propertyList(from: plist, format: nil) as? [String: String]) ?? [:]

        } else {

            productList = [:]

        }



        products = []



        Task {

            await fetchProducts()

        }

    }

    

    @MainActor

    func fetchProducts() async {

        do {

            let storeProducts = try await Product.products(for: productList.keys)



            var newProducts: [Product] = []



            for product in storeProducts {

                newProducts.append(product)

            }

        } catch {

            print("Failed product request from the App Store server: \(error)")

        }

    }



    func isPurchased(_ product: Product) async throws -> Bool {

        return purchasedProducts.contains(product)

    }

    

    func purchase(_ product: Product) async throws -> Bool {

        let result = try await product.purchase()

        switch result {

            case .success:

                print("Product has been purchased.")

                return true

            case .userCancelled, .pending:

                return false

            default:

                return false

        }

    }



    func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {

        switch result {

        case .unverified:

            throw StoreError.failedVerification

        case .verified(let safe):

            return safe

        }

    }



    @MainActor

    func updateProductStatus() async {

        var purchasedProducts: [Product] = []

        for await result in Transaction.currentEntitlements {

            do {

                let transaction = try checkVerified(result)



                if let product = products.first(where: { $0.id == transaction.productID }) {

                    purchasedProducts.append(product)

                }

            } catch {

                print()

            }

        }

        self.purchasedProducts = purchasedProducts

    }

    

}

This is what I have in my view within my app.

                    Section(

                        header: Text("Products")

                    ) {

                        ForEach(store.products) { product in

                            Button(

                                action: {

                                    // Nothing.

                                },

                                label: {

                                    Text("Product: " + product.displayName)

                                    Spacer()

                                    Text(product.displayPrice)

                                }

                            )

                        }

                    }

When I run the app, it builds successfully but it just shows the section heading and then it's blank underneath. What am I doing wrong here which means that my product is not loading?

I have;

  • added the in-app purchase capability in my app
  • added the product into a plist file in my app
  • added the product into my app within App Store Connect
  • added my products into the product config file in Xcode
  • added the state object reference at the top of my view
  • added the StoreKit scheme to my app

I don't think I've missed anything else out here.

Can someone please help me with where I'm going wrong? I've read so many tutorials and watched so many videos and they literally all explain it a different way.

I'm attempting to do the same thing.

Are you getting errors in the console? Here's what I'm getting:

2022-12-09 11:35:17.208256-0800 StoreDemo1[20986:8095799] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")

2022-12-09 11:35:17.208310-0800 StoreDemo1[20986:8095799] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")

2022-12-09 11:35:17.208380-0800 StoreDemo1[20986:8095799] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")

2022-12-09 11:35:17.273253-0800 StoreDemo1[20986:8095825] [Default] [StoreKit] Did not receive any products or error for products request.

I've just checked my console and I'm seeing the following, single error message:

[StoreKit] Did not receive any products or error for products request.
I can't get StoreKit to work and I don't know how to debug it
 
 
Q