Настройка In-App Review (запрос отзыва) в мобильном приложении
SKStoreReviewRequest на iOS и In-App Review API на Android — это нативные диалоги, которые позволяют пользователю оставить оценку без выхода из приложения. Конверсия нативного диалога значительно выше, чем у кастомного popover с предложением «перейти в App Store».
iOS: SKStoreReviewRequest
import StoreKit
// iOS 16+
func requestReviewIfAppropriate() {
guard let scene = UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
else { return }
SKStoreReview.requestReview(in: scene)
}
Ключевое ограничение: Apple позволяет показывать диалог не более 3 раз за 365 дней независимо от того, как часто вызывается requestReview. Вызов сверх лимита — iOS просто не показывает диалог. Никакого callback о том, был ли диалог показан, — нет.
Это означает: три момента показа в год — это весь бюджет. Тратить их на пользователей, которые только что установили приложение, — расточительно. Оптимальный момент:
- После завершения основного action (пользователь достиг цели)
- После N сессий (5–10), не при первом запуске
- После позитивного события: первый успешный платёж, первый завершённый проект
Проверка в Xcode Simulator: диалог показывается каждый раз, не подчиняясь лимиту — это только для разработки. На реальном устройстве — лимит работает.
Android: In-App Review API
// build.gradle
implementation 'com.google.android.play:review:2.0.1'
implementation 'com.google.android.play:review-ktx:2.0.1'
class MainActivity : AppCompatActivity() {
private lateinit var reviewManager: ReviewManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
reviewManager = ReviewManagerFactory.create(this)
}
fun requestInAppReview() {
val request = reviewManager.requestReviewFlow()
request.addOnCompleteListener { task ->
if (task.isSuccessful) {
val reviewInfo = task.result
val flow = reviewManager.launchReviewFlow(this, reviewInfo)
flow.addOnCompleteListener {
// Диалог завершён (или не был показан)
// Нет информации о том, оставил ли пользователь отзыв
}
}
}
}
}
Аналогично iOS: Google не гарантирует, что диалог будет показан. Внутренняя квота Google — неизвестна публично, но по практике: не более одного раза в 30 дней на пользователя. Попытка вызвать launchReviewFlow чаще — диалог не появится без ошибки.
Тестирование на Android
В DEBUG-сборке диалог не работает реалистично. Для тестирования — FakeReviewManager:
val reviewManager = if (BuildConfig.DEBUG) {
FakeReviewManager(context)
} else {
ReviewManagerFactory.create(context)
}
FakeReviewManager всегда показывает диалог без квот — удобно для QA.
Момент запроса: главный фактор
Неверный момент — главная причина низкой конверсии In-App Review. Типичные антипаттерны:
- При первом запуске: пользователь ещё не понял ценность
- При ошибке или неудачном действии: запрос отзыва после краша
- При выходе из приложения: диалог перекрывает процесс, раздражает
- Принудительно через 3 дня после установки без учёта активности
Что работает: запрос после того, как пользователь продемонстрировал вовлечённость. Например, в приложении для чтения — после завершения третьей книги. В трекере привычек — после 7-дневного стрика. В e-commerce — после второго успешного заказа.
Обходной путь при достижении лимита
Когда квота исчерпана, нативный диалог не появится. Стандартная практика: предложить пользователю перейти в магазин через deeplink.
// iOS — deeplink в App Store на страницу отзывов
let appID = "123456789"
let url = URL(string: "https://apps.apple.com/app/id\(appID)?action=write-review")!
UIApplication.shared.open(url)
// Android — deeplink в Google Play
val uri = Uri.parse("market://details?id=${packageName}")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
Показывать этот deeplink только пользователям с высоким NPS или после явного позитивного сигнала.
Процесс работы
Определение оптимального момента для запроса на основе пользовательского флоу.
Интеграция SKStoreReviewRequest (iOS) и In-App Review API (Android).
Настройка FakeReviewManager для тестирования.
Опциональный fallback на deeplink для пользователей за пределами квоты.
Ориентиры по срокам
Интеграция In-App Review для iOS и Android — 2–4 часа. С разработкой логики определения момента показа на основе пользовательских событий — 1 день.







