托管型应用内购买内容恢复异常:startDownloads失效、updatedDownloads未触发
Hey there, let's dig into this flaky hosted IAP restoration issue you're facing on macOS—now that you've nailed down a consistent trigger scenario, we can target the root cause effectively. Here are my top recommendations to diagnose and fix the problem:
Inspect transaction queue details immediately on launch
When you get the notification about two pending restore transactions, log every detail of each transaction right away to spot anomalies. Duplicate transactions often come from incomplete prior attempts, and one might have empty or corrupted download objects. Add this logging to yourupdatedTransactionshandler:func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { print("Transaction ID: \(transaction.transactionIdentifier ?? "No ID")") print("State: \(transaction.transactionState.rawValue)") print("Downloads count: \(transaction.downloads?.count ?? 0)") print("Product ID: \(transaction.payment.productIdentifier)") } }This will confirm if both transactions have valid downloads attached, or if one is a stale entry that's blocking the workflow.
Audit your
provideContentimplementation for race conditions
SinceprovideContent(_ transaction: SKPaymentTransaction)is firing butstartDownloadsisn't working, check for common pitfalls here:- Are you calling
SKPaymentQueue.default().startDownloads(transaction.downloads!)right away, or is there async logic (like waiting for a network call) that might be losing the transaction reference? - Do you hold a strong reference to the transaction until downloads complete? Weak references can cause the transaction to deallocate before the download process even starts.
- Make sure you aren't accidentally finishing the transaction before starting the downloads—this will abort any pending download tasks.
- Are you calling
Validate macOS sandbox entitlements and permissions
macOS sandboxed apps have strict access rules that can break hosted IAP downloads without clear errors. Double-check:- Your app has the
com.apple.security.network.cliententitlement (required to fetch the hosted content over the network) - The
com.apple.developer.in-app-purchaseentitlement includes all your hosted product IDs - Your app has write access to the directory where you plan to save downloaded content. Test this by creating a dummy file in that directory at launch to rule out permission issues.
- Your app has the
Reset the SKPaymentQueue sandbox state
Corrupted sandbox data is a common culprit for intermittent IAP issues. Try this full reset:- Quit your app and Xcode entirely
- Go to
System Settings > App Store > Sandbox Accountand sign out of your test account - Delete the app from your Mac
- Delete the sandbox cache folder:
~/Library/Containers/[Your App Bundle ID]/Data/Library/Application Support/com.apple.appstore - Restart your Mac, sign back into the sandbox account, and rebuild/run the app from Xcode
Test with a fresh sandbox account
Sometimes test accounts get stuck with pending or corrupted transactions. Create a new sandbox test account in App Store Connect, use it to purchase the hosted IAP, then try restoring. If the issue doesn't happen with the new account, the original test account was likely in a bad state.
If you still hit the problem after these steps, add logging to paymentQueue(_:didFinishDownloads:)—even if updatedDownloads isn't firing, this method might report failures that can point to the issue. Also, check the Console app for any hidden error messages from StoreKit that aren't showing up in your app's logs.
内容的提问来源于stack exchange,提问作者Andriy Gordiychuk

