💻 Android

[Android/IOS] 인앱 리뷰 기능 추가하기

2023. 9. 23. 23:13

 

요약

  1. 리뷰 API를 호출하더라도, 할당량에 따라 호출되지 않을 수 있음 (Android 1달에 2번, IOS 1년에 3번)
  2. 사용자가 앱을 충분히 경험한 후 & 경험이 단절되지 않는 위치에 적절히 넣어야 함
  3. 리뷰를 무조건 달게 하려면 or 문구를 추가하거나 상황에 따라 직접 처리하려면 그냥 수동으로 앱스토어로 이동시켜야 함(=딥링크)

 

Android

요청 시기
  • 사용자가 유용한 의견을 제공할 수 있을 정도로 충분히 앱 또는 게임을 사용한 이후
  • 버튼 등으로 유도하는 것은 안됨 (뜨지 않는 경우 앱이 멈추지 않게)
 
조건
  • 사용자는 PlayStore가 설치되어 있고 & API 21 이상이어야 함
  • 리뷰 대화상자를 표시할 수 있는 빈도에 관한 시간제한 할당량 有 → 1개월에 최대 2번
    • 이를 넘어가면 대화상자가 표시되지 않으며, 이는 Google Play에서 정함
    • 따라서 버튼 등으로 유도하는 것은 X (뜨지 않는 경우, 단절된 경험)
  • 요청 전에 어떤 질문도 해서는 안됨 (ex. ‘앱이 마음에 드십니까?’, '이 앱을 별 5개로 평가하시겠습니까?')
    • 기존 디자인을 수정하거나, 오버레이를 추가하거나 등 안됨
 

 

IOS

조건
  • 1년에 최대 3번까지 평가 요청 가능, 같은 버전에서는 2번 이상 뜨지 않음
  • 유저 행동을 interrupt 하지 않아야 함 (ex. 앱 처음 시작, 유저 액션의 결과 등)
  • 시스템 제공 프롬프트 사용
 
요청 시기
  • 사람들이 앱이나 게임에 대한 참여를 보여준 후에만 요청
  • 앱이나 게임에서 등급 요청이 덜 귀찮을 수 있는 자연스러운 중단 또는 중지 지점 선택
  • 사람들이 귀하의 경험에 대한 추가 참여를 보여준 후에 다시 메시지를 표시 (최소 1-2주의 간격)

 

적용 방법 - Android

1. build.gradle에 Google Play Core 라이브러리 추가
dependencies {
    // This dependency is downloaded from the Google’s Maven repository.
    // So, make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.play:review:2.0.1'
}

 

2. ReviewManager 객체 생성 후, ReviewInfo 객체 요청
ReviewManager manager = ReviewManagerFactory.create(this);
Task<ReviewInfo> request = manager.requestReviewFlow();
request.addOnCompleteListener(task -> {
    if (task.isSuccessful()) {
        // We can get the ReviewInfo object
        ReviewInfo reviewInfo = task.getResult();
    } else {
        // There was some problem, log or handle the error code.
        @ReviewErrorCode int reviewErrorCode = ((ReviewException) task.getException()).getErrorCode();
    }
});

 

3. 인앱 리뷰 실행
*SharedPreference 등으로 마지막 요청한 날짜 등을 확인한 후에 요청
Task<Void> flow = manager.launchReviewFlow(activity, reviewInfo);
flow.addOnCompleteListener(task -> {
    // The flow has finished. The API does not indicate whether the user
    // reviewed or not, or even whether the review dialog was shown. Thus, no
    // matter the result, we continue our app flow.
});
 
+) 테스트
  • PlayStore에 프로덕션 앱이 게시되어 있거나
  • 내부 테스트를 통해 테스트하거나 (할당량 한도가 적용되지 않음)
  • FakeReviewManager를 사용
  • requestInAppReview()
    • 릴리즈 버전에서만 작동
 

적용 방법 - IOS

  • 앱 버전 비교하여 띄울지 결정 → 리뷰를 안 남겼는데, 버전이 다르면 띄워야 함 → count 비교
  • Prompt를 띄우기 전에 delay를 주어 사용자가 하던 일을 방해하지 않도록 처리 必
// If the app doesn't store the count, this returns 0.
var count = UserDefaults.standard.integer(forKey: UserDefaultsKeys.processCompletedCountKey)
count += 1
UserDefaults.standard.set(count, forKey: UserDefaultsKeys.processCompletedCountKey)
print("Process completed \(count) time(s).")


// Keep track of the most recent app version that prompts the user for a review.
let lastVersionPromptedForReview = UserDefaults.standard.string(forKey: UserDefaultsKeys.lastVersionPromptedForReviewKey)


// Get the current bundle version for the app.
let infoDictionaryKey = kCFBundleVersionKey as String
guard let currentVersion = Bundle.main.object(forInfoDictionaryKey: infoDictionaryKey) as? String
    else { fatalError("Expected to find a bundle version in the info dictionary.") }

 // Verify the user completes the process several times and doesn’t receive a prompt for this app version. (해당 버전에서는 최대 4번까지 review prompt 요청 가능) 
 if count >= 4 && currentVersion != lastVersionPromptedForReview {
     Task { @MainActor [weak self] in
         // Delay for two seconds to avoid interrupting the person using the app.
         // Use the equation n * 10^9 to convert seconds to nanoseconds.
         // 화면 interrupt 방지하기 위해 2초 정도 딜레이
         try? await Task.sleep(nanoseconds: UInt64(2e9))
         if let windowScene = self?.view.window?.windowScene,
            self?.navigationController?.topViewController is ProcessCompletedViewController {
             SKStoreReviewController.requestReview(in: windowScene)
             UserDefaults.standard.set(currentVersion, forKey: UserDefaultsKeys.lastVersionPromptedForReviewKey)
        }
     }
 }

 

+) 테스트
  • develoment mode에서는 항상 뜸
  • TestFlight에 배포하면 실제 동작하는 대로 제한 O
 

적용 방법 - 수동으로 이동

  • 버튼을 눌렀을 때 등처럼 무조건 이동해야 하는 경우
  • 마켓의 리뷰 달기 화면으로 직접 이동시켜주어야 함
// IOS - 리뷰 입력으로 이동 
@IBAction func requestReviewManually() {
    guard let writeReviewURL = URL(string: "https://apps.apple.com/app/id<#Your App Store ID#>?action=write-review")
        else { fatalError("Expected a valid URL") }
    UIApplication.shared.open(writeReviewURL, options: [:], completionHandler: nil)
}

// Android - 마켓으로만 이동 
new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.golfzonretail"))

 

 


 

기타 Tips

  • 유저가 만족한 경험을 한 후에 넣는 것이 좋음 (ex. 성공적으로 구매 완료)
    • 사용자가 만족할 만한 경험을 하는 곳이 어딘지 확인해야!
  • 앱이 안정화되기 전에는 오히려 역효과일 수 있음
    • 좋은 경험 < 나쁜 경험에 대해 항의하기 위해 쓰는 경우가 多
    • 따라서, 오히려 낮은 별점을 편하게 다는 것(?)을 장려하게 되는 꼴
  • In-App Review 대신 수동으로 이동하는 방식도 多 고려함
    • 만족한 경우는 리뷰로, 불만족한 경우는 문의하기로 넘기고자 하는 경우가 많은데
    • In-App Review를 띄우기 전에는 어떤 문구도 띄울 수 X
    • 따라서, 설정 메뉴 등에 해당 액션들을 따로 추가하는 방법도 많이들 고려함
  • 문구를 가볍게 설정
    • 평가해 달라는 말 대신 문구를 잘 선택하는 것도 중요
    • 친근한 말투도 Good
    • 단, 좋은 평점을 받기 위해 보상을 주는 것은 금지되어 있음
  • 팝업이 오히려 부정적인 경험을 줄 수 있음
    • 팝업 대신 화면에 넣는다거나 하는 방식도 있음
 
In-App Review
  • 제약 多
  • But, 앱 내에서 바로 리뷰를 입력할 수 있어 편하다
 
수동 이동
  • 피드백, 리뷰를 분기해서 받을 수 있음 & 문구 직접 지정 가능
  • 위치를 직접 지정할 수 있다 (팝업이 아니더라도 화면 내에 넣거나...)
  • But, 스토어에서 직접 입력해야 하므로 중간에 이탈할 가능성이 높다
 
 

'💻 Android' 카테고리의 다른 글

[Android] Android CI/CD 구축하기 (1) - Firebase App Distribution, Play store 테스트 트랙  (0) 2024.05.25
[Android] Android 13 마이그레이션  (0) 2024.03.09
[Android] 인스타그램 DM으로 공유하기 기능 만들기  (0) 2023.09.23
[Android/MySQL] 안드로이드에서 JDBC 사용하기  (0) 2022.11.08
[Android/Kotlin] 갤러리에서 이미지 가져오기  (0) 2022.08.02
'💻 Android' 카테고리의 다른 글
  • [Android] Android CI/CD 구축하기 (1) - Firebase App Distribution, Play store 테스트 트랙
  • [Android] Android 13 마이그레이션
  • [Android] 인스타그램 DM으로 공유하기 기능 만들기
  • [Android/MySQL] 안드로이드에서 JDBC 사용하기
시니유
시니유
UX 개선에 관심이 많은 Frontend & Android 개발자
  • 시니유
    시니유의 개발 블로그
    시니유
  • 전체
    오늘
    어제
    • 분류 전체보기 (23)
      • 💻 Web (2)
      • 💻 Android (8)
      • 🔥 대외활동 (8)
      • ⚒️ 기타 (5)
  • 최근 댓글

  • 링크

    • Github
    • LinkedIn
    • Resume
  • hELLO· Designed By정상우.v4.10.0
시니유
[Android/IOS] 인앱 리뷰 기능 추가하기
github 상단으로

티스토리툴바