I've been playing with Apple's StoreKit 2 demo code (buying the cars, subscriptions, ...), and sometimes when I purchase a car, one or more of the other buttons visually flip state (e.g., purchased checkmark changes back to the price).
Leaving the StoreView and returning to it shows the correct state for each of the buttons.
I am using the StoreKit Configuration Products.storekit (for the scheme), so testing in Xcode.
I get this in both the simulator and on my actual phone.
The issue is random. The vast majority of the time everything works perfectly.
Is anyone else seeing this issue?
Does anyone know how to address it?
Dev environment:
- Xcode 13.0 beta 5 (13A5212g)
- macOS 12.0 Beta (21A5534d)
- Mac mini (M1, 2020)
I figured out how to replicate the unexpected behavior and how to solve it.
To replicate the bug:
I launch the program from Xcode, buy two items in the store, then stop the program via Xcode. Then I launch the program again via Xcode, return to the store view (which shows the two items I purchased earlier with their green checkmarks). I buy a third item, at which point the green checkmarks next to the previously purchased items (from the first run of the program) disappear and are replaced by the prices (indicating I hadn’t bought them).
In a nutshell, when I launch the program the second time, the Store's purchasedIdentifiers set is empty. When that set is updated (with a new purchase), the previously purchased items check to see if their product ID is in the set; they aren't; they changed their buttons from green checkmarks to blue buttons with the price.
For the curious, the code that initially displays the green checkmark for the previously purchased items sets the variable "isPurchased" in the .onAppear block (see ListCellView), and the code that updates the button (which messes up the previously purchased items in the second run of the program when purchasing a new item) uses the .onChange block.
One solution (which might not be elegant) is to replace the line in the .onChange block with the same line in the .onAppear block.