Prompting users to review your app
Learn how to use StoreKit 2 to prompt users to review your app from within the app.
The number of your app reviews and the actual ratings they receive are crucial to the success of your app within the App Store. Many reviews with a rating of 4 stars or above have an impact on the algorithm that recommends your app in search results over other apps in the same category. Additionally, users who are considering downloading your app will also care about good ratings. They build trust, and good ratings will motivate users to give you a good rating themselves if the experience matches the good ratings they saw on your App Store page.
However, it is also true that many users will never even consider rating your app, simply because they forget about it. After using your app for a while, they would have to remember to go back to the App Store, search for your app, find it, and then scroll down to see the options to give it a rating. For most users, this level of friction is too high to prompt them to provide a rating, even if it is an app they love using. Being mindful of this, Apple offers developers a handy framework to request a rating from users within their app.
It is contained within StoreKit 2, introduced in iOS 16, and is called RequestReviewAction. This environment value will give you the power to request a user review three times within 365 days whenever you desire to do so.
But when is the best time to ask your users for a review? Some best practices Apple suggests following are:
- Request at a time that doesn’t interrupt what someone is trying to achieve in your app, for example, at the end of a sequence of events that they successfully complete.
- Avoid showing a request for a review immediately when a user launches your app, even if it isn’t the first time it launches.
- Avoid requesting a review as a result of a user action.
The concrete implementation to prompt the user for a review looks as follows:
- Access the environment value
@Environment(\.requestReview) private var requestReview - Call a function to present the review request:
@Environment(\.requestReview) private var requestReview
private func presentReview() {
Task {
try await Task.sleep(for: .seconds(2))
await requestReview()
}
}
The delay ensures that the user is finished with the action executed before the review request, so you don’t interrupt their workflow. A good article to learn techniques and best practices is Requesting App Store reviews on the Apple Developer portal.
It has a sample project attached that explores more techniques like detecting on which app version the user was last prompted for a review to avoid doing it again for the same version.
Below is a minimal example showing how you can track whether a review prompt was already shown for the current app version:
import Foundation
@MainActor
final class ReviewPromptManager {
static let shared = ReviewPromptManager()
private let lastPromptedVersionKey = "lastPromptedVersion"
private var currentAppVersion: String? {
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
}
/// Returns `true` if this app version hasn’t shown a review prompt yet.
func canRequestReview() -> Bool {
guard let currentAppVersion else { return false }
let lastPromptedVersion = UserDefaults.standard.string(forKey: lastPromptedVersionKey)
return lastPromptedVersion != currentAppVersion
}
/// Call this after showing the review prompt.
func markReviewRequested() {
guard let currentAppVersion else { return }
UserDefaults.standard.set(currentAppVersion, forKey: lastPromptedVersionKey)
}
}
Usage:
private func presentReview() {
guard ReviewPromptManager.shared.canRequestReview() else { return }
Task {
try? await Task.sleep(for: .seconds(2))
await requestReview()
ReviewPromptManager.shared.markReviewRequested()
}
}
Prompting for a review works exceptionally well in Apps where the user regularly receives positive feedback, such as habit trackers. After completing a streak of 10 days for a habit, that would be a good example to prompt a review. Additionally, Apps that trigger users’ emotions, such as games, benefit from encouraging a review after a game round is won, for example.
struct HabitDetailView: View {
@Environment(\.requestReview) private var requestReview
let habitName: String
@State private var currentStreak: Int = 9
var body: some View {
VStack(spacing: 16) {
Text(habitName)
.font(.title.bold())
Text("Current streak: \(currentStreak) days")
.foregroundStyle(currentStreak == 10 ? .green : .primary)
Button("Mark today as done") {
currentStreak += 1
// Example condition: prompt after a 10-day streak
if currentStreak == 10 {
presentReviewAfterDelay()
}
}
.buttonStyle(.borderedProminent)
}
.padding()
}
private func presentReviewAfterDelay() {
Task {
// Give the UI a moment to “settle” after the success action
try? await Task.sleep(for: .seconds(2))
requestReview()
}
}
}
If you follow these best practices, you're likely to motivate users to give you a good rating. However, there is also a privacy setting in iOS that allows users to globally disable apps from requesting a review. Generally, you can expect many users to be willing to give a review, but there are, of course, many people out there who, for whatever reason, never give reviews. Most of the time, this is due to them being more "consumers" of online content rather than "providers". They probably also don't write comments on social media or post a lot.