A toot by my buddy Casey introduced again some irritating recollections about expired subscriptions that haven’t expired (sure, actually). This weblog submit will hopefully enable you keep away from having these identical recollections.
All of it begins when a buyer contacts you with a screenshot that appears one thing like this:
Your code and the App Retailer don’t agree about when a subscription expired. The reason for that is Apple’s StoreKit pattern code. It’s possible that you’ve some code much like line 246 of Retailer.swift:
subscriptionGroupStatus = strive? await subscriptions.first?.subscription?.standing.first?.state
That code will work nice till you encounter a buyer that has Household Sharing enabled, as most do. The problem is that the Product.SubscriptionInfo can include a number of objects, and the code above solely checks the primary one.
How can that occur? With Household Sharing, the people who find themselves utilizing the subscription act independently: one could subscribe for a yr after which cancel. Then one other might subscribe at a later date for under a month. You need to verify all the subscriptions, not simply the primary one. One thing like this:
if let statuses = strive? await subscriptions.first?.subscription?.standing {
let checkStatus = statuses.first $0.state == .inGracePeriod
…
}
The documentation and pattern code doesn’t say it, so I’ll: Apple’s StoreKit pattern doesn’t assist Household Sharing.
For those who’re on the lookout for code from Apple that does assist Household Sharing, you will discover it buried in one of many WWDC demo apps. Clearly.
What’s most irritating about this example is that you understand it exists in case you’ve learn the documentation:
The array can have a couple of subscription standing in case your subscription helps Household Sharing. Present the client with service for the subscription based mostly on the very best stage of service the place the state is subscribed.
Which is not sensible till you’ve learn the paragraphs above.
Truly, I used to be flawed. Probably the most irritating factor about this example is that it’s basically untestable. You may’t reproduce the issue, even after a buyer lets you understand they’re having points and also you’ve learn this weblog submit. That’s as a result of there may be:
No solution to check this in Xcode (even when it’s turned on in .storekit configuration).No solution to check this in TestFlight (faux purchases don’t use Household Sharing).No affordable solution to check this in manufacturing (pink flags will likely be raised with refunding and altering purchases repeatedly whereas testing with actual Apple IDs).
The StoreKit check harness in Xcode has been a godsend, however on this case it’s simply less than the duty. And the result’s a lot of pissed off builders who’re testing code in manufacturing on a buyer’s gadget.
Apple of us: you may be taught extra in FB13212468. It’s been closed as “Investigation full” — perhaps you need to ask Casey if he agrees with that decision.