티스토리 뷰

728x90
반응형

사용자가 스토어에서 앱을 설치할 때, 안심하고 앱을 다운받는데에 가장 중요한 지표가 되는 것은 단연 스토어 내 리뷰라고 볼 수 있다.

특히 내가 원하는 기능을 하는 앱을 검색하면 적어도 2개 이상은 비슷한 앱 리스트가 나오는데, 이럴 때 스토어 리뷰를 보고 앱 사용성이나 얼마나 많은 사용자들이 최근까지도 앱을 이용하고 있는지 미리 파악하고 다운받게 된다.

 

그런데 반대로 내가 어떠한 앱을 이용하고 있는 사용자일 때를 생각해보면, 서비스를 이용할 때에만 앱을 사용하지

이 앱을 사용하면서 만족감을 느꼈다 할지라도 스토어까지 찾아가서 리뷰를 작성했던 경험은 없었다.

단, 리뷰를 작성해달라고 자연스럽게 앱 내에서 팝업으로 요청이 오면 기쁜 마음으로 리뷰를 작성해주곤 했다.

 

인앱 리뷰 요청 모달

 

자주 사용하는 앱에서 위와 같은 모달 팝업을 자주 경험해봤을 것이다.

이렇게 앱 내에서 스토어 리뷰를 요청하는 것을 인앱 리뷰(In-App Review) 라고 명칭하는데,

이번 포스팅에서는 React Native 환경에서 사용자에게 인앱 리뷰를 요청하는 방법을 알아보도록 하자.


📌 라이브러리 사용하기

인앱 리뷰는 굉장히 많은 서비스에서 사용되다보니 당연히 React Native용 npm 라이브러리가 배포되어있다.

 

https://www.npmjs.com/package/react-native-in-app-review

 

react-native-in-app-review

react native in app review, to rate on Play store, App Store, Generally, the in-app review flow (see figure 1 for play store, figure 2 for ios) can be triggered at any time throughout the user journey of your app. During the flow, the user has the ability.

www.npmjs.com

 

https://github.com/oblador/react-native-store-review

 

GitHub - oblador/react-native-store-review: Rate on App/Play Store directly in your React Native app

Rate on App/Play Store directly in your React Native app - oblador/react-native-store-review

github.com

 

위에 링크한 두 라이브러리가 가장 많이 사용되는데,

개인적으로 사용한다면 최근까지도 커밋 내역이 있는 react-native-in-app-review를 추천한다.

라이브러리로 적용하는 방법은 사용법이 매우 간단하기에 README를 보고 참고하길 바란다.


📌 Native Module 작성하기

라이브러리를 사용하는 방법보단 간단하진 않지만,

알고보면 너무 간단하니 괜히 package.json에 한줄 추가하지 말고 이 방법을 따라해보길 추천한다.

 

1️⃣ Android 세팅하기

 

1. app/build.gradle dependencies 추가하기

review와 review-ktx 패키지를 사용하기 위해 아래와 같이 추가해준다.

 

...
dependencies {
    ...
    // 인앱 리뷰
+    implementation 'com.google.android.play:review:2.0.1'
+    implementation 'com.google.android.play:review-ktx:2.0.1'
    ...

 

2. 자바 클래스 생성하기

APP 패키지 내, InAppReviewPackage.java 클래스를 생성해준다.

(경로를 헷갈려하시는 분들이 많은데, 패키지명이 com.test라면 app/java/com/test 경로에 생성해준다)

 

InAppReviewPackage.java

package com.test;

import androidx.annotation.NonNull;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;

public class InAppReviewPackage implements ReactPackage{
    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactApplicationContext) {
        return Arrays.<NativeModule>asList(new InAppReviewModule(reactApplicationContext));
    }

    @NonNull
    @Override
    public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactApplicationContext) {
        return Collections.emptyList();
    }
}

 

같은 경로에 InAppReviewModule.java 모듈 클래스도 생성해준다.

 

InAppReviewModule.java

package com.test;

import android.app.Activity;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.module.annotations.ReactModule;
import com.google.android.play.core.review.ReviewInfo;
import com.google.android.play.core.review.ReviewManager;
import com.google.android.play.core.review.ReviewManagerFactory;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

@ReactModule(name = InAppReviewModule.NAME)
public class InAppReviewModule extends ReactContextBaseJavaModule{
    public static final String NAME = "InAppReview";

    private final ReactApplicationContext reactContext;

    public InAppReviewModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return NAME;
    }

    @ReactMethod
    public void rate(final Callback callback) {
        final ReviewManager manager = ReviewManagerFactory.create(this.reactContext);
        Task<ReviewInfo> request = manager.requestReviewFlow();
        request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>() {
            @Override
            public void onComplete(@NonNull final Task<ReviewInfo> requestTask) {
                if (requestTask.isSuccessful()) {
                    ReviewInfo reviewInfo = requestTask.getResult();
                    Activity activity = getCurrentActivity();
                    if (activity == null) {
                        callback.invoke(false, "getCurrentActivity() unsuccessful");
                        return;
                    }
                    Task<Void> flow = manager.launchReviewFlow(activity, reviewInfo);
                    flow.addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> flowTask) {
                            if (requestTask.isSuccessful()) {
                                callback.invoke(true);
                            } else {
                                callback.invoke(false, "launchReviewFlow() unsuccessful");
                            }
                        }
                    });
                } else {
                    callback.invoke(false, "requestReviewFlow() unsuccessful");
                }
            }
        });
    }
}

 

3. 생성한 모듈 클래스 추가하기

MainApplication.java의 getPackages()에 아래와 같은 코드를 추가하여 생성한 모듈을 RN 패키지에 등록해준다.

 

MainApplication.java

@Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          
          // 인앱리뷰 추가
+            packages.add(new InAppReviewPackage());

          return packages;
        }

 

여기까지 왔다면 Android 세팅은 끝났다. 이제 iOS 세팅으로 넘어가보자


2️⃣ iOS 세팅하기

1. XCode > 프로젝트 경로 내 InAppReview.h 헤더파일 생성하기

XCode > 프로젝트명 우클릭 > New File

 

파일명은 InAppReview.h 로 작성해준다

#import <React/RCTBridgeModule.h>
#import <React/RCTConvert.h>
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>

@interface InAppReview : NSObject <RCTBridgeModule>

@end

 

2. 같은 방식으로 InAppReview.m 파일을 생성해준다.

1.의 팝업창에서 Objc-C File(m이라고 적혀있는 아이콘) 을 선택해주면 된다

 

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import "InAppReview.h"
#import "React/RCTConvert.h"

@implementation InAppReview
RCT_EXPORT_MODULE();
 
RCT_EXPORT_METHOD(rate: (RCTResponseSenderBlock) callback) {
  NSString *AppleAppID = @"Your AppleAppID"; // Your AppleAppID
  NSString *AppleNativePrefix = @"itms-apps://itunes.apple.com/app/id";
  NSString *suffix = @"?action=write-review";

  NSString *url = [NSString stringWithFormat:@"%@%@%@", AppleNativePrefix, AppleAppID, suffix];
  
      if ([SKStoreReviewController class]) {
          dispatch_async(dispatch_get_main_queue(), ^{
                  NSSet *scenes = [[UIApplication sharedApplication] connectedScenes];
                  NSArray *scenesArray = [scenes allObjects];

                  UIWindowScene *activeScene;
                  for (int i = 0; i < scenes.count; i++) {
                      UIWindowScene *scene = [scenesArray objectAtIndex:i];
                      NSInteger activationState = scene.activationState;
                      if (activationState == UISceneActivationStateForegroundActive) {
                          activeScene = scene;
                      }
                  }

                  if (activeScene != nil) {
                      [SKStoreReviewController requestReviewInScene:activeScene];
                  } else {
                      NSLog(@"No active scenes found. Cannot requestReviewInScene.");
                  }
          });
      }
}

@end

 

중간에 AppleAppID에는 iOS 프로젝트의 APP ID를 넣어주면 된다.

App Store Connect의 앱 정보 > 일반 정보 섹션에서 확인할 수 있다.


3️⃣ React Native 코드 작성하기

작성한 네이티브 모듈을 불러오는 함수를 작성해보자.

나는 utils/functions.ts 파일 내에 선언하였다.

 

functions.ts

import {Platform, NativeModules} from 'react-native';

type RateAppCallback = (response: any) => void;

export const rateApp = (callback: RateAppCallback): void => {
  const {InAppReview} = NativeModules;

  if (Platform.OS === 'ios') {
    InAppReview?.rate((response: any, error: any) => {
      callback({response, error});
    });
  } else if (Platform.OS === 'android') {
    InAppReview?.rate((response: any, error: any) => {
      callback({response, error});
    });
  }
};

 

이제 불러오고 싶은 화면이나 이벤트 함수에서 위 rateApp을 호출하면 바로 앱 리뷰 요청 팝업이 노출될 것이다.


⚠️ 주의사항

인앱리뷰를 사용자에게 요청할 때 Android, iOS에서는 다음과 같이 정책을 정해두었는데,

 

Android : 1번 노출 후 1개월 정도의 시간 뒤에 다시 노출 (정확한 시간은 구글의 마음)

iOS : 365일 내 최대 3번 정도 노출

 

디버깅 할 때에는 iOS는 횟수 제한은 없는 것 같고, 안드로이드는 1번 노출 후 다시 노출이 되지 않으므로 꼭 참고할 것.

 

그리고 공통적으로, 인앱 리뷰 팝업 내의 디자인을 포함한 레이아웃, 텍스트 등을 수정을 하면 안된다고 한다.

 

이렇게 NativeModule을 작성해서 In-App Review 요청 기능을 만드는 방법을 알아봤다.

생각보다는 간단했고 재밌던 경험이었다.

 

부족한 글이지만 꼭 이 글을 보는 모두에게 좋은 경험으로 작용했으면 좋겠다 😄


참고문서 : https://medium.com/@deepanshujain_33606/in-app-review-in-react-native-android-ios-18f06b95ae58

728x90
반응형
반응형
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함