Post

Replies

Boosts

Views

Activity

Reply to Why doesn’t Transaction.updates emit reliably?
I have run some tests on my copy of StoreKit testing project. When the app is not active, and a renewal comes through, it will be unfinished. The listener task you have in Transaction.updates might not catch it. Question: Does your app handle unfinished transactions? You need to listen for Transaction.unfinished, and finish any verified transactions. Either call it on the next launch, or create another Task to listen for unfinished. func processUnfinishedTransactions() async { for await result in Transaction.unfinished { switch result { case .verified(let verified): // Always finish verified transactions await verified.finish() case .unverified(let unverified, _): // Handle unverified } } } If you check the Understanding StoreKit Workflows sample from WWDC25, notice they have 3 things going on in the Store.swift file: Task(priority: .background) { // Finish any unfinished transactions -- for example, if the app was terminated before finishing a transaction. for await verificationResult in Transaction.unfinished { await handle(updatedTransaction: verificationResult) } // Fetch current entitlements for all product types except consumables. for await verificationResult in Transaction.currentEntitlements { await handle(updatedTransaction: verificationResult) } } Task(priority: .background) { for await verificationResult in Transaction.updates { await handle(updatedTransaction: verificationResult) } } Although it uses @Observable, your shared singleton should be able to keep these tasks alive. The same principles apply.
Topic: App & System Services SubTopic: StoreKit Tags:
Feb ’26
Reply to Why doesn’t Transaction.updates emit reliably?
Your listenerTask will update the purchasedProducts/purchasedSubscriptions. If there is any change in the Transaction.updates, you can update the array. With Observable, your views will update accordingly to this change. Take a look at the WWDC25 sample on Understanding StoreKit workflows. https://developer.apple.com/documentation/StoreKit/understanding-storekit-workflows
Topic: App & System Services SubTopic: StoreKit Tags:
Feb ’26
Reply to Why doesn’t Transaction.updates emit reliably?
Update the customer product status using for await result in Transaction.currentEntitlements { // Verify transaction and append to the product items/subscription items. } Also its better to use @Observable class on your InAppPurchaseManager instead of a shared singleton, especially if your project is iOS 17+. You would have: var purchasedProducts: [Product] = [] var purchasedSubscriptions: [Product] = [] Check out tutorials online on how to create Observable StoreKit 2 manager.
Topic: App & System Services SubTopic: StoreKit Tags:
Feb ’26
Reply to SwiftUI view state resetting after alert is shown
I tested the sample code, even using a random color to debug the view to check if it is being recreated, it looks like VStack in List = unstable identity when presentation state changes. I applied .border() modifier with the random color, to track if a view is recreated. Only when the presentation state changes, then the count is reset. Color( red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1) ) Separate the buttons to test, and when the isPresented flag changes after the alert, the LibraryView in the VStack causes issues. private struct ViewWithAlert: View { @State private var isPresented: Bool = false @State private var presentedCount = 0 var body: some View { VStack { // Test without alert - just increment the counter Button { // isPresented = true // Comment out alert presentedCount += 1 } label: { Text("Increment count: \(presentedCount)") .border(Color.random) } // Separate button to show alert // -> When tapped, presentedCount resets to 0 on tap OK Button("Show Alert") { isPresented = true } } .alert("Hello", isPresented: self.$isPresented) { Button("OK") { } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Jan ’26
Reply to HELP WITH SUBSCRIPTIONS
If you are using SubscriptionStoreView with groupID overload, make sure the groupID entered is matching with the one in App Store Connect, not the one from your Xcode StoreKit configuration file. In Xcode testing, you need a StoreKit config file, and make sure to select Edit Scheme -> Options tab and select StoreKit Configuration to the correct configuration file. But this does not affect your App Store version. You might need to handle unfinished transactions. Take a look at sample code from WWDC25 on StoreKit 2.
Topic: App & System Services SubTopic: StoreKit Tags:
Jan ’26
Reply to Why doesn’t Transaction.updates emit reliably?
I have run some tests on my copy of StoreKit testing project. When the app is not active, and a renewal comes through, it will be unfinished. The listener task you have in Transaction.updates might not catch it. Question: Does your app handle unfinished transactions? You need to listen for Transaction.unfinished, and finish any verified transactions. Either call it on the next launch, or create another Task to listen for unfinished. func processUnfinishedTransactions() async { for await result in Transaction.unfinished { switch result { case .verified(let verified): // Always finish verified transactions await verified.finish() case .unverified(let unverified, _): // Handle unverified } } } If you check the Understanding StoreKit Workflows sample from WWDC25, notice they have 3 things going on in the Store.swift file: Task(priority: .background) { // Finish any unfinished transactions -- for example, if the app was terminated before finishing a transaction. for await verificationResult in Transaction.unfinished { await handle(updatedTransaction: verificationResult) } // Fetch current entitlements for all product types except consumables. for await verificationResult in Transaction.currentEntitlements { await handle(updatedTransaction: verificationResult) } } Task(priority: .background) { for await verificationResult in Transaction.updates { await handle(updatedTransaction: verificationResult) } } Although it uses @Observable, your shared singleton should be able to keep these tasks alive. The same principles apply.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Feb ’26
Reply to Why doesn’t Transaction.updates emit reliably?
Your listenerTask will update the purchasedProducts/purchasedSubscriptions. If there is any change in the Transaction.updates, you can update the array. With Observable, your views will update accordingly to this change. Take a look at the WWDC25 sample on Understanding StoreKit workflows. https://developer.apple.com/documentation/StoreKit/understanding-storekit-workflows
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Feb ’26
Reply to Why doesn’t Transaction.updates emit reliably?
Update the customer product status using for await result in Transaction.currentEntitlements { // Verify transaction and append to the product items/subscription items. } Also its better to use @Observable class on your InAppPurchaseManager instead of a shared singleton, especially if your project is iOS 17+. You would have: var purchasedProducts: [Product] = [] var purchasedSubscriptions: [Product] = [] Check out tutorials online on how to create Observable StoreKit 2 manager.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Feb ’26
Reply to SwiftUI view state resetting after alert is shown
I tested the sample code, even using a random color to debug the view to check if it is being recreated, it looks like VStack in List = unstable identity when presentation state changes. I applied .border() modifier with the random color, to track if a view is recreated. Only when the presentation state changes, then the count is reset. Color( red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1) ) Separate the buttons to test, and when the isPresented flag changes after the alert, the LibraryView in the VStack causes issues. private struct ViewWithAlert: View { @State private var isPresented: Bool = false @State private var presentedCount = 0 var body: some View { VStack { // Test without alert - just increment the counter Button { // isPresented = true // Comment out alert presentedCount += 1 } label: { Text("Increment count: \(presentedCount)") .border(Color.random) } // Separate button to show alert // -> When tapped, presentedCount resets to 0 on tap OK Button("Show Alert") { isPresented = true } } .alert("Hello", isPresented: self.$isPresented) { Button("OK") { } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
Jan ’26
Reply to Swipe to go back still broken with Zoom navigation transition.
Actually if you look at the DestinationVideo sample project (https://developer.apple.com/documentation/visionos/destination-video) It uses the matchedTransitionSource/navigationTransition zoom APIs. When I tested it building on Xcode 26.2 on an iPhone 15 Pro Max, when swiping back the child view very quickly, the source view will "disappear".
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’26
Reply to HELP WITH SUBSCRIPTIONS
If you are using SubscriptionStoreView with groupID overload, make sure the groupID entered is matching with the one in App Store Connect, not the one from your Xcode StoreKit configuration file. In Xcode testing, you need a StoreKit config file, and make sure to select Edit Scheme -> Options tab and select StoreKit Configuration to the correct configuration file. But this does not affect your App Store version. You might need to handle unfinished transactions. Take a look at sample code from WWDC25 on StoreKit 2.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Jan ’26