10.5 C
New York
Wednesday, February 26, 2025

StoreKit 2 Not Fetching Merchandise in Sandbox (iOS 18.2, Xcode 16.2, macOS 15.3.1)


I’m struggling to get StoreKit 2 to fetch merchandise in my SwiftUI app whereas utilizing a sandbox person. I feel I’ve adopted all mandatory setup steps in Xcode, App Retailer Join, and my bodily check gadget, however Product.merchandise(for:) at all times returns an empty array. I’d admire any insights!

What I’ve Finished

  1. Native App Setup (Xcode 16.2)

    • Created a clean SwiftUI Xcode venture.

    • Enabled In-App Buy functionality beneath Signing & Capabilities.

    • Carried out minimal StoreKit 2 code to fetch out there merchandise (see under).

    • Utilizing the proper bundle identifier, which matches App Retailer Join.

  2. App Retailer Join Configuration

    • Registered the app with the identical bundle identifier.

    • Created an Auto-Renewable Subscription with: Product ID v1 (matches my code). All fields crammed (pricing, localization, and many others.). Standing: Prepared for Assessment.

  3. Sandbox Person & Testing Setup

    • Created a sandbox tester account.

    • On my bodily gadget (iOS 18.2): Logged in with the sandbox person beneath Settings → Developer → Sandbox Apple ID. Put in and ran the app instantly from Xcode.

  4. Challenge: StoreKit Returns No Merchandise

    Product.merchandise(for:["v1"]) doesn’t return any merchandise.

    • There are not any errors thrown, simply an empty array.

    • I confirmed that StoreKit Configuration is ready to None in Xcode.

    • No StoreKit-related logs seem within the Console.

Code Snippets

//StoreKitManager.swift

import StoreKit
import SwiftUI

@MainActor
class StoreKitManager: ObservableObject {
    @Revealed var merchandise: [Product] = []
    @Revealed var errorMessage: String?

    func fetchProducts() async {
        do {
            let productIDs: Set = ["v1"] // Matches App Retailer Join
            let fetchedProducts = attempt await Product.merchandise(for: productIDs)
            print(fetchedProducts) // Debug output

            DispatchQueue.essential.async {
                self.merchandise = fetchedProducts
            }
        } catch {
            DispatchQueue.essential.async {
                self.errorMessage = "Did not fetch merchandise: (error.localizedDescription)"
            }
        }
    }
}
//ContentView.swift

import SwiftUI

struct ContentView: View {
    @StateObject personal var storeKitManager = StoreKitManager()

    var physique: some View {
        VStack {
            if let errorMessage = storeKitManager.errorMessage {
                Textual content(errorMessage).foregroundColor(.crimson)
            } else if storeKitManager.merchandise.isEmpty {
                Textual content("No merchandise out there")
            } else {
                Record(storeKitManager.merchandise, id: .id) { product in
                    VStack(alignment: .main) {
                        Textual content(product.displayName).font(.headline)
                        Textual content(product.description).font(.subheadline)
                        Textual content("(product.value.formatted(.forex(code: product.priceFormatStyle.currencyCode ?? "USD")))")
                            .daring()
                    }
                }
            }

            Button("Fetch Merchandise") {
                Process {
                    await storeKitManager.fetchProducts()
                }
            }
        }
        .padding()
        .onAppear {
            Process {
                await storeKitManager.fetchProducts()
            }
        }
    }
}

#Preview {
    ContentView()
}

Further Info
• iOS Model: 18.2
• Xcode Model: 16.2
• macOS Model: 15.3.1
• Gadget: Bodily iPhone (not simulator)
• StoreKit Configuration: Set to None

Is there any technique to debug why StoreKit isn’t recognizing my subscription?

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles