I've got a basic Storekit setup for my app, allowing users to send a tip if they're enjoying the app.
What I'd like help with:
Resolving the warning: Making a purchase without listening for transaction updates risks missing successful purchases. Create a Task to iterate Transaction.updates at launch.
Code
Ok, so here's the code I use in my AboutView.swift
(simplified):
import SwiftUI
import StoreKit
struct AboutScreen: View {
// Binding for our sheet
@Binding var isPresented: Bool
// States for Storekit
@State var products: [Product] = []
// Our IAPs
let iapProductIDs = Set([
"MYAPP.iaps.smallTip",
"MYAPP.iaps.mediumTip",
"MYAPP.iaps.largeTip",
])
var body: some View {
NavigationView {
VStack {
// Only display if we have products
if products.count != 0 {
ForEach(products) { product in
Button {
Task.init {
try await purchaseProduct(product)
}
} label: {
HStack {
Text(product.displayName)
Spacer()
Text(product.displayPrice)
}
}
}
}
// The rest of the view
// ...
}
.navigationTitle("About")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
isPresented = false
} label: {
Text("Close")
}
}
}
}
.task {
await fetchProducts()
}
}
// Fetch our products and save them to `products`
func fetchProducts() async {
do {
self.products = try await Product.products(for: iapProductIDs)
} catch {
print("STOREKIT: Unable to fetch products")
}
}
// Buy a product
func purchaseProduct(_ product: Product) async throws -> StoreKit.Transaction {
let result = try await product.purchase()
switch result {
case .pending:
throw PurchaseError.pending
case .success(let verification):
switch verification {
case .verified(let transaction):
print("STOREKIT: Successfully purchased \(product.displayName)")
await transaction.finish()
return transaction
case .unverified:
throw PurchaseError.failed
}
case .userCancelled:
throw PurchaseError.cancelled
@unknown default:
assertionFailure("Unexpected result")
throw PurchaseError.failed
}
}
enum PurchaseError: Error {
case pending, failed, cancelled
}
}
The purchase runs successfully in the simulator, but throws the following warning:
Making a purchase without listening for transaction updates risks missing successful purchases. Create a Task to iterate Transaction.updates at launch.
I've been looking online for a few hours and I can't reallly understand how to resolve this without using an entirely new storekit setup. The tutorials I've looked at all approach this differently, which is confusing me a lot.