Auto-renewing Subscription Updates not Arriving

This is a copy of a reply to this post. https://developer.apple.com/forums/thread/722222?page=1

I'm posting as new in the hope someone might have more up-to-date information, as I'm pulling out what little hair I have left.

I'm using Storekit 2, testing in Xcode with a local Storekit config file. I have created a very minimal system to investigate this issue. I have a SwiftUI-based window using SubscriptionStoreView, and my app set up with the usual listener. I have four types of auto renewing subscription, configured in the local Storekit config file.

With my app running, I subscribe to the lowest-level subscription I offer, via the SubscriptionStoreView. Notification of the inital purchase arrives, but subsequent auto-renewals do not trigger any action in my listener for Transaction.updates. They arrive as expected in the Transaction Manager. Radio silence in my listener.

If I upgrade one subscription (via my SubscriptionStoreView) I see this reflected in the UI immediately, and also in the Transaction Manager, but the update that arrives in Transaction.updates refers to the old subscription, and has the isUpgraded flag set to false.

Also, can anyone remind me what the grey warning triangle next to entries in the Transaction Manager means. I'm assuming it means unfinished, as that's what the sidebar indicates.

Can the testing system really be this broken, or am I wildly off the mark? Unless I'm doing something fundamentally wrong this all seems extremely flakey, but happy to be proved wrong.

I find this all rather unsettling if I can't test reliably, and am concerned that I my app may end up in this situation if I use storekit 2:

https://stackoverflow.com/questions/73530849/storekit-renewal-transactions-missing-in-transaction-all-or-transaction-updates

UPDATE: I swapped to Sandbox testing with a renewal period of 3 minutes. Still no auto-renew notifications delivered to the running app. If I kill the app and restart it, I get a stream of them when the app starts (as reported by others).

If I upgrade my subscription via my UI I DO get the correct upgrade notification immediately in the App, but I get two of them. As previously, I then get no further auto-renew notifications.

*** UPDATE ***

Not sure I made it clear previously but I'm developing a Freemium update to a previously paid Mac App. The discussion below relates to StoreKit testing in Xcode.

After a week of experimenting I'm now in possession of more facts, and have a clearer idea of how to express what I'm looking for. I contacted Apple with a TSI and was told that the forums were the way to go, and an Apple engineer would look at this post, so here goes.

I've distilled the purchase/subscription situation into the diagram below. The boxes are a simplified notion of "state", and the arrows connecting them are in effect state transitions, caused by the labelled "events". Some of the content is empirical, gleaned from experimenting.

I want to be able to receive timely notifications in my app, of each event occurrence, so I can write rigorous (reactive) code to capture my business logic.

To attempt to achieve this I'm listening for two things:

  1. Transaction changes, via Transaction.updates()
  2. Subscription status changes, via Product.SubscriptionInfo.Status.updates()

Obviously, when (if) I detect these transitions I call Transaction.currentEntitlements() to examine the latest subscription information and make functionality available to the customer. I've put a hook in both observers to update my product entitlements when this happens.

Some observations:

  • When making changes in the Transaction Manager such as cancelling or refunding, neither occurrence causes either of my two listeners to fire. I have no idea if this works on the live system, but I need to be able to test it without it being live...

  • If I subsequently restore purchases manually in my app, the listeners then fire. Clearly I don't want to have to do this and I can't expect customers to do it.

  • Auto-renew occurrences that show in the Transaction Manager don't cause my listeners to fire. Perhaps I'm naively assuming that a subscription auto-renew constitutes a subscription change event.

  • Any event that causes a transition back to "Not Subscribed" in my diagram doesn't appear to be detectable through current entitlements (which does actually make sense), so I'm assuming if you want to give customers information about this kind of thing you'd have to display Transactions.all in some form. Cancellation, billing retry failed, revoked, etc. I haven't rigorously tested all of these cases yet but my preliminary experiments indicate there's no actual notification of them via my listeners. You can observe them retrospectivelly by examining Transactions.all

Am I listening for the wrong things? How do I get notified of these events in my app at the time they actually happen, without manual intervention? I can't rely on users restarting the app (which does usually result in up-to-date info arriving), as many people leave their macs and applications running for extended periods.

One final thing, I can't find a way to cancel subscriptions in Sandbox. Do you just have to wait for the finite set of auto-renews to finish?

Oh and dumping Transactions.all causes the warning triangles in the Transaction Manager to go away :)

*** FURTHER UPDATE ***

I've done some more rigorous testing and improved my state diagram. The diagram is more representative of what actuallly happens, but there are a few awkward edge cases to do with billing retry that aren't represented.

For each "event" I set up the testing conditions and monitored what happened. The red numbered circles are the events where I didn't receive any automatic notification, but could get the listeners to fire by manually restoring the subscription or restarting the app.

The dark red circles are the business critical ones. If I don't detect these, users will be able to continue using functionality they aren't entitled to.

Is there anyone out there with similar problems? :)

SO....

I built an iOS app with StoreKit, and ran it in the simulator.

I attached three listeners using SwiftUI hooks:

  1. .subscriptionStatusTask()
  2. .task, to listen for Transaction.updates and Transaction.unfinished

I also added these to My Mac App, same code.

All three fired in the iOS app, at the expected points, for every transaction of interest. Great.

None of them fired in the Mac app, at the expected points, for the transaction missing in my previous diagram.

Not impressed.

FINALLY...

After building multiple apps and experimenting, I believe I have finally found what the issue is.

If you have objective-C machinery in your app, in addition to Swift or SwiftUI, the StoreKit2 listeners don't fire. In particular, if your app launch code is objective-C, StoreKit2 dispatching doesn't work properly.

I doubt Apple are intending to do anything about this as they seem to be dropping objective-C like a hot stone...

None of them fired in the Mac app, at the expected points, for the transaction missing in my previous diagram.

Can you file a bug report about this using Feedback Assistant?

(Replying to DTS Engineer)

With all due respect to you personally, I don't think it's worth my time.

I can't see that Apple are likely to fix it, as it's a legacy problem.

I've had similar situations in the past, filed bug reports, and nothing has happened. I've already wasted far too much time on this, and the TSI staff were (uncharacteristically) not helpful, pushing me to the forums instead of being willing to look into the matter. I started this post a couple of weeks ago, and have had zero response until your message.

Apologies if I come across as irritated. I know it's not your fault personally. I've been focusing solely on Mac Dev for the last 20 years and have struggled against a gradual decline in the quality of Apple's implementations, regression issues, and poor documentation.

IMHO Apple need to spend more time solidifying the systems they already have, rather than always producing the next thing, year-on-year, and letting relatively new technology wither in the background.

Auto-renewing Subscription Updates not Arriving
 
 
Q