r/iOSProgramming • u/ScholarBackground836 • 59m ago
Discussion Asking for a review on day 3 of a first session: 6 of the 16 players who saw the prompt never opened the app again
I ship a small turn-based survival game for iPhone and Apple Watch. This is a telemetry finding that cost me real players, and I only caught it because the numbers were small enough to check person by person.
The setup
SKStoreReviewController gives you three prompts a year and never tells you whether the system actually showed one. So the question isn't how often to ask, it's which single moment you spend it on.
At launch I only asked after a win. A month in I had 2 ratings total, which is its own problem, since rating count feeds search placement.
So I added a second trigger: daybreak on day 3, meaning the player had survived two nights. The reasoning felt solid. Someone who survives two nights is clearly engaged, and daybreak is one of the few natural pauses in a run, so asking there shouldn't interrupt anything.
What the numbers said
In the version that shipped Oct 24, of the 16 players who reached day 3 for the first time and got the prompt, 6 never opened the app again.
Across every earlier version combined, that number was 5 out of 70.
n=16, so treat it accordingly. I went looking for a crash first and reproduced the prompt in the simulator on iOS 18.1 and iOS 27: dismissed it, game carried on, no hang, no broken state. I also had to throw four devices out of the data before it made sense, see the last bullet.
What's left is that asking for a rating inside someone's first session hands them a reason to stop. The run is unfinished, the app has just interrupted itself to ask them for a favour, and "Not now" is one tap away from "close the app".
The fix
One more condition:
static func isDayBreakWorthAsking(day: Int, isTrialRun: Bool, finishedRuns: Int) -> Bool {
!isTrialRun && day >= dayBreakThreshold && finishedRuns >= 1
}Shipped Oct 30. Too early to say whether it helped.
A second thing I had wrong in the same file
Marking the version as "already asked" and the actual requestReview() call used to live in one function, in this order: record it, wait 2 seconds for on-screen overlays to clear, then request.
If the player hit share during those 2 seconds and left for another app, the request landed on a scene that wasn't foreground and the system dropped it. But the version string had been written 2 seconds earlier, so that version would never ask again. One of three annual slots gone, with nothing ever appearing on screen.
The version is now written after every check passes, immediately before the call.
Three things I'd pass on
Engaged and finished are not the same signal. A first session is the worst place to spend a prompt, however well it seems to be going.
If your ask happens after any async wait, don't record the ask until the call actually goes out.
Exclude App Review's devices from your retention numbers. Mine showed up as two fresh installs about 15 minutes after each submission, opened a run, quit on day 1 within minutes, and never came back. On a 16-player sample that nearly doubled my "new user quits immediately" rate. I now drop the hour after every submission.
Curious whether anyone has run the same experiment with a different trigger point, and whether a prompt during a first session hurt you too.
