G'day folks,
I had a bug the other day in my receipt verification code, which caused a crash. Fixed the bug, but since it was caused ultimately by an unexpected response from the backend, I thought "I should probably handle this edge case".
The obvious solution is to persist the transaction state while we're processing it, before calling finishTransaction and marking it as complete. The docs for finishTransaction hint at this being good practice.
However, I hit a brick wall when it came to actually finishing the transaction after a crash. SKPaymentTransaction doesn't conform to Codable or NSSecureCoding. There's no constructor for it. I thought I might be handed the transaction again through paymentQueue(_:updatedTransactions:), as would happen if the call to finishTransaction failed, but that doesn't happen. Restoring purchases doesn't work either, as this is a consumable IAP and doesn't show up there.
Here's the thing: I don't even know what happens if you never call finishTransaction. Presumably, at some point, the user is refunded? There must be a time limit. I don't know, since I'm in the sandbox environment and I can't even see the transactions on my account, much less whether or not I'm getting refunded. (That makes debugging this super difficult, by the way. Is there a way around that? Some way to say "yes, this sandbox user's fake account was charged this much fake money"?)
Is there some way to prod StoreKit into handing over any unfinished transactions? What's the best practice here?
Post
Replies
Boosts
Views
Activity
Here is my situation:
I'm working on an app that has background music. This should obviously be muted by the silent switch. For this reason, I'm using AVAudioSession category ambient.
However, part of the app is a list of audio samples. Each one has a preview button, a big ol' rightwards facing triangle ▶️. That's a play button, and by tapping it the user is unambiguously indicating they want to hear the audio. But in ambient, those sounds are silenced if the silent switch is enabled; the play button switches to pause, the progress indicator runs as normal, but no sound comes out. To the user, this looks like a bug. I can't even tell them why it's not working, because there's no API to tell that it's not.
Ok, fine, I can switch the category to playback and we'll hear them… but then we'll also hear the background music suddenly fade in, and then back out after we're done playing the sample.
Alright, so we can pause the BGM before changing the category and playing the sample, then change it back and unpause the BGM. This now works as expected if you have the device on silent.
But these are only samples – sound effects, really – and they should play over the background music, not interrupt it. If we don't have the silent switch enabled, we get the BGM suddenly fading out before playing our sample, and that's almost as bad.
Basically, I feel like I'm being hamstrung by the all-or-nothing nature of the AVAudioSession. There are some sounds I want to play regardless of the position of the silent switch, and others that I want to mute if the silent switch is enabled. But I have no idea how to do that, or if it's even possible.
Basically, here are the options as I see them, and the issues with each of them.
Category
Silent
Ring
Issue
playback
Plays all audio
Plays all audio
Unacceptable, BGM overrides silent switch
ambient
Plays no audio
Plays all audio
Sample list appears broken when device is silenced
ambient => playback
Plays BGM and SFX when user presses play button
Plays correctly
Weird fade in of background music when silenced
ambient => playback, pausing BGM
Plays correctly
BGM pauses before playing SFX
Weird fade out of background music when not silenced
Can anyone offer any advice, here?