Reputation: 30196
I’m struggling to get StoreKit 2 to fetch products in my SwiftUI app while using a sandbox user. I think I’ve followed all necessary setup steps in Xcode, App Store Connect, and my physical test device, but Product.products(for:)
always returns an empty array. I’d appreciate any insights!
What I’ve Done
Local App Setup (Xcode 16.2)
• Created a blank SwiftUI Xcode project.
• Enabled In-App Purchase capability under Signing & Capabilities.
• Implemented minimal StoreKit 2 code to fetch available products (see below).
• Using the correct bundle identifier, which matches App Store Connect.
App Store Connect Configuration
• Registered the app with the same bundle identifier.
• Created an Auto-Renewable Subscription with: Product ID v1 (matches my code). All fields filled (pricing, localization, etc.). Status: Ready for Review.
Sandbox User & Testing Setup
• Created a sandbox tester account.
• On my physical device (iOS 18.2): Logged in with the sandbox user under Settings → Developer → Sandbox Apple ID. Installed and ran the app directly from Xcode.
Issue: StoreKit Returns No Products
• Product.products(for:["v1"])
does not return any products.
• There are no errors thrown, just an empty array.
• I confirmed that StoreKit Configuration is set to None in Xcode.
• No StoreKit-related logs appear in the Console.
Code Snippets
//StoreKitManager.swift
import StoreKit
import SwiftUI
@MainActor
class StoreKitManager: ObservableObject {
@Published var products: [Product] = []
@Published var errorMessage: String?
func fetchProducts() async {
do {
let productIDs: Set<String> = ["v1"] // Matches App Store Connect
let fetchedProducts = try await Product.products(for: productIDs)
print(fetchedProducts) // Debug output
DispatchQueue.main.async {
self.products = fetchedProducts
}
} catch {
DispatchQueue.main.async {
self.errorMessage = "Failed to fetch products: \(error.localizedDescription)"
}
}
}
}
//ContentView.swift
import SwiftUI
struct ContentView: View {
@StateObject private var storeKitManager = StoreKitManager()
var body: some View {
VStack {
if let errorMessage = storeKitManager.errorMessage {
Text(errorMessage).foregroundColor(.red)
} else if storeKitManager.products.isEmpty {
Text("No products available")
} else {
List(storeKitManager.products, id: \.id) { product in
VStack(alignment: .leading) {
Text(product.displayName).font(.headline)
Text(product.description).font(.subheadline)
Text("\(product.price.formatted(.currency(code: product.priceFormatStyle.currencyCode ?? "USD")))")
.bold()
}
}
}
Button("Fetch Products") {
Task {
await storeKitManager.fetchProducts()
}
}
}
.padding()
.onAppear {
Task {
await storeKitManager.fetchProducts()
}
}
}
}
#Preview {
ContentView()
}
Additional Information • iOS Version: 18.2 • Xcode Version: 16.2 • macOS Version: 15.3.1 • Device: Physical iPhone (not simulator) • StoreKit Configuration: Set to None
Is there any way to debug why StoreKit isn’t recognizing my subscription?
Upvotes: 0
Views: 26