Fighting App Store rejection due to reviewer's sandbox
Over the past two weekends, I decided to build a new app. Whisper Memos. In short, it’s an iOS app that lets you record a voice memo, converts to text using OpenAI Whisper technology, and sends you an email with the transcription.
Building the UI in SwiftUI was easy. It’s just a basic list view with a few modals for things like settings. The database part was easy too. Simple Firebase setup, with some processing on the server side.
For running Whisper library, there are two options: Deepgram API, currently free, or spinning up a model on banana.dev. The latter should be about $1.5 per hour of recording.
The surprisingly most annoying part was the subscriptions. I decided to use RevenueCat, to make sure there’s very little work for me to do. For implementation, RevenueCat is very easy:
func purchase(package: Package) {
self.isPurchasing = true
Purchases.shared.purchase(package: package) { transaction, customerInfo, error, userCancelled in
self.isSubscribed = customerInfo?.entitlements["amber"]?.isActive ?? false
self.isPurchasing = false
}
}
Submitting to the App Store was not that easy. I got stuck on this issue:
We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, the subscription content was not unlocked after the purchase. Please review the details and resources below and complete the next steps.
And behold, they sent me a screenshot where the subscriptions don’t work. At first, I tried the strategy of just making a minor change and resubmitting. Sometimes even just a new build fixes the problem.
But this was worse. After going back and forth 3 times, they kept sending me the same problem. Something was not right.
The first thing you’ll want to do in this situation is to log the error somewhere to cloud. I was already using Firebase, so I just wrote the possible error during purchase:
Purchases.shared.purchase(package: package) { transaction, customerInfo, error, userCancelled in
if let error = error {
self.errorsStore.create(error: "Error purchasing: (error.description)")
}
// ...
}
And sure enough I got error code MISSING_RECEIPT_FILE, “The receipt is missing”:
Error purchasing: Error Domain=RevenueCat.ErrorCode Code=0 "Unknown error."
UserInfo={source_file=RevenueCat/PurchasesOrchestrator.swift:403,
source_function=purchase(sk2Product:promotionalOffer:completion:),
NSUnderlyingError=0x283b7db30 {Error Domain=RevenueCat.ErrorCode Code=9 "The
receipt is missing."
UserInfo={source_function=handlePurchasedTransaction(_:storefront:),
source_file=RevenueCat/PurchasesOrchestrator.swift:687,
readable_error_code=MISSING_RECEIPT_FILE, NSLocalizedDescription=The receipt is
missing.}}, NSLocalizedDescription=Unknown error., readable_error_code=UNKNOWN}
After Googling this, two forum topics looked useful:
- AppStore rejection: The receipt is not valid
- Apple rejects build because of error The receipt is missing
I tried resubmitting a bunch of times - that never worked. I tried asking the reviewer to try and log in with another Sandbox account, also no success.
Finally I tried a bit of advice that I saw in one of the forum threads: Delete all your subscriptions, and create new ones, with different IDs.
Miraculously this finally worked and the app got approved. It took about 10 attempts. I was lucky to get a quick review on each attempt.
So go ahead, and try Whisper Memos! I’m just hoping that the next time I submit an update, it won’t be as painful.