*** 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 :)