I would like to determine which app version the user first downloaded. For that, I'm using StoreKit and the originalAppVersion
property of AppTransaction
:
let verificationResult = try await AppTransaction.shared
switch verificationResult {
case .verified(let appTransaction):
return "\(appTransaction.originalAppVersion) (\(appTransaction.environment.rawValue))"
case .unverified(let appTransaction, let verificationError):
// The app transaction didn't pass StoreKit's verification.
The code runs fine, but always returns "1.0" for the app version and "Sandbox" for the environment. I tried debug/release builds and even pushed a build to TestFlight.
Is the only way to test this to push a new App Store version that should go live?
Yes, it seems that the sandbox always returns "1.0" for originalAppVersion
, and TestFlight uses the sandbox (as does app review). On the other hand, StoreKit Testing in Xcode (using a StoreKit configuration file) always seems to return the current version set in your project. So the only time you get the "real original version" seems to be in production.
I ran into this when developing a new version of my app which switched from a paid model to freemium, and wanted to automatically upgrade existing users to premium.
I ended up testing the auto-upgrade logic by using the sandbox (where the "1.0" essentially always simulates an existing user), and using a StoreKit configuration file to test the case of a new user.
However, another wrinkle is that, because Apple's reviewers use the sandbox, they always look like "existing users", so if your code hides the in-app purchase option in that case, they'll never get to see it and will reject your app as a result.
So, to ensure the reviewers get the in-app purchase option, my code skips the auto-upgrade if the transaction is from the sandbox and it's not a Debug build. You can do this with an #if
to check the compiler configuration, and then checking whether AppTransaction.shared.environment
is .sandbox
.
It's a bit nerve-racking that there's no true end-to-end test with a real originalAppVersion
before production, but I haven't found a way around this.