Yes, I understand the mechanics of what's needed in code. That's not what my question was about.
Post
Replies
Boosts
Views
Activity
UPDATE:
I contacted Apple via Developer Support, in addition to the TSI I sent in. The advantage of that is that I got to speak to someone and explain the problem. They sent me an email requesting details - I submitted these, a screenshot and a video of the problem. It is currently in the works, being looked at....
I will keep you posted.
Thanks for making this known. I'm in the same situation converting my app from Paid to Freemium, and am completely stuck. I really can't risk putting it live without being able to properly test it.
What to do?
I've sent a TSI in, asking DTS engineers to respond. No idea whether they will.
Same problem here.
Completely stuck.
I've sent a TSI in, asking DTS engineers to respond. No idea whether they will.
Same issue here. All works fine in Sandbox
(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.
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...
SO....
I built an iOS app with StoreKit, and ran it in the simulator.
I attached three listeners using SwiftUI hooks:
.subscriptionStatusTask()
.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.
*** 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? :)
*** 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:
Transaction changes, via Transaction.updates()
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 :)
I'm in the same situation. Your solution does work, but it's based on manual intervention.
I would like my app to be informed of subs renewing, cancellation, refunds, billing issues etc...all the stuff a proper app would want, in order to make business decisions. I'm not using my own server, so I want to do all of this within my app. In my (limited) experience, this info doesn't appear to get posted via Transaction.currentEntitlements
Looking at the Transaction Manager in Xcode, entries in the log update automatically when things change. Apple are either polling for this, or they have a notification solution that I've so far been unable to discover. I've tried listening for subscription status changes, but my listener never fires for the above listed cases.
You can manually get some stuff if you call Transaction.all and wade through it. When you call it, it does often cause any listeners you've set up to fire, leading me to believe there are some synch issues there.
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.
Any "updates" on this? :)
It's still not working (for me) in June 24.
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 a local Storekit config file.
With my app running, I subscribe to the lowest-level subscription I offer, via the SubscriptionStoreView. 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.
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.
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.
FWIW I posted this as a new thread here:
https://developer.apple.com/forums/thread/758315
I'm getting this using Xcode storekit testing as of today. It was working fine, and now I can't test in Xcode or the Sandbox. A mix of error messages, mostly referencing server hostnames not being found.
Anyone know what's happening?