ReactNative

React Native 앱 버전 제어 react-native-version-check로 업데이트 관리

HA젠옹 2025. 2. 23. 21:45
반응형
앱이 업데이트 될 때마다 사용자들에게 최신 버전으로 사용하게 만들기 위해 어떠한 방법이 있을까? 라는걸 찾다가 발견한 라이브러리를 소개할려고 합니다. 해당 라이브러리는 react-native-version-check 라이브러리로 현재 사용 중인 앱 버전과 스토어에 업로드 된 버전을 비교하여 다를 경우 스토어로 이동시켜 업데이트를 할 수 있게 도와주는 라이브러리입니다.

이번 글에서는 해당 라이브러리가 어떠한 기능이 있으며, 해당 라이브러리를 사용하여 만들 수 있는 간단한 예제 화면을 보여드릴 겁니다.

1. 라이브러리 소개

react-native-version-check는 React Native 앱의 버전을 확인하고, 업데이트 여부를 쉽게 관리할 수 있도록 도와주는 라이브러리입니다. 주요 기능에 대해 다음과 같습니다.

현재 앱 버전 확인: 앱의 package.json 또는 네이티브 설정에서 버전 정보 추출

스토어 버전 확인: Google PlayStore 또는 App Store에 등록된 최신 버전을 가져옴

업데이트 필요 여부 판단: 시멘틱 버저닝(메이저, 마이너, 패치)을 기반으로 업데이트 필요 여부 결정

업데이트 알림: 사용자에게 업데이트를 유도하는 팝업 또는 커스텀 UI 제공


2. 주요 기능 및 메서드 설명

메서드 명 반환 값 설명
getCountry() Promise<country: String> 디바이스의 국가 코드를 반환
getPackageName() packageName: String 앱의 패키지 이름 반환
getCurrentBuildNumber() buildNumber: Number 현재 앱 빌드 번호 반환
getStoreUrl([option]) Promise<storeUrl: String> 스토어 (PlayStore/App Store)의 앱 URL 반환
getAppStoreUrl([option]) Promise<storeUrl: String> App Store URL 반환
getPlayStoreUrl([option]) Promise<storeUrl: String> Play Store URL 반환
getCurrentVersion() currentVersion: String 현재 앱 버전 반환
getLatestVersion([option])
Promise<latestVersion: String> 스토어에 등록된 최신 버전 반환 (파싱 오류 시 null 반환 가능)
needUpdate([option])
Promise<result: Object> 업데이트 필요 여부를 포함한 객체 반환예시: { isNeeded, currentVersion, latestVersion, storeUrl }

 

💡 needUpdate()의 옵션

currentVersion: 현재 앱 버전 (생략 시 내부적으로 getCurrentVersion() 사용)

latestVersion: 스토어의 최신 버전 (생략 시 getLatestVersion() 사용)

depth: 버전 비교 깊이 (1: 메이저, 2: 마이너, 3: 패치)

forceUpdate: 강제 업데이트 여부

provider: 최신 버전 조회 방법 ( ‘appStore’ or ‘playStore’ 혹은 사용자 정의 함수)

 

자세한 내용은 GitHub - kimxogus/react-native-version-check에서 확인할 수 있습니다.

 

GitHub - kimxogus/react-native-version-check: A version checker for react-native applications

A version checker for react-native applications. Contribute to kimxogus/react-native-version-check development by creating an account on GitHub.

github.com


3. 환경 설정

3.1 라이브러리 설치

# npm
npm i react-native-version-check

# yarn
yarn add react-native-version-check

 

3.2 IOS 설정

ios/Podfile에 아래 내용을 추가합니다.

pod 'react-native-version-check', :path => '../node_modules/react-native-version-check'

 

3.3 Android 설정

1. android/settings.gradle

include ':react-native-version-check'
project(':react-native-version-check').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-version-check/android')

 

2. android/app/build.gradle

dependencies {
    // 다른 의존성들...
    implementation project(':react-native-version-check')
}

 

3. android/app/src/main/java/[…]/MainApplication.java

import io.xogus.reactnative.versioncheck.RNVersionCheckPackage;  // 추가

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new RNVersionCheckPackage()  // 추가
    );
}

4. 사용 예제

4.1. 기본 버전 체크 예제

아래 예제는 앱 실행 시 현재 버전과 스토어의 최신 버전을 비교하여 업데이트 필요 시 기본 Alert 창을 띄워 사용자가 업데이트하도록 안내하는 기본 UI 예제 코드 입니다.

import React, { useEffect } from 'react';
import { Alert, Linking } from 'react-native';
import VersionCheck from 'react-native-version-check';

const App = () => {
  useEffect(() => {
    const checkForUpdate = async () => {
      try {
        const currentVersion = VersionCheck.getCurrentVersion();
        console.log('현재 앱 버전:', currentVersion);

        // Android인 경우 'playStore' 옵션 사용 (iOS는 기본값이 'appStore')
        const latestVersion = await VersionCheck.getLatestVersion({ provider: 'playStore' });
        console.log('최신 앱 버전:', latestVersion);

        // 업데이트 필요 여부 확인 (기본적으로 메이저 버전 기준)
        const updateInfo = await VersionCheck.needUpdate({
          provider: 'playStore',
          depth: 2  // 마이너 버전까지 비교
        });

        if (updateInfo.isNeeded) {
          Alert.alert(
            '업데이트 안내',
            '새로운 버전이 출시되었습니다. 최신 버전으로 업데이트 해주세요.',
            [
              {
                text: '지금 업데이트',
                onPress: async () => {
                  try {
                    const storeUrl = updateInfo.storeUrl || await VersionCheck.getStoreUrl({ provider: 'playStore' });
                    Linking.openURL(storeUrl);
                  } catch (urlError) {
                    console.error('스토어 URL 열기 실패:', urlError);
                  }
                }
              },
              { text: '나중에', style: 'cancel' }
            ],
            { cancelable: false }
          );
        }
      } catch (error) {
        console.error('버전 체크 중 에러 발생:', error);
      }
    };

    checkForUpdate();
  }, []);

};


export default App;

 

 

4.2. 강제 업데이트 및 커스텀 UI

강제 업데이트

중요 보안 패치 등으로 강제 업데이트가 필요할 경우, “나중에” 버튼을 제거하여 업데이트를 반드시 진행하도록 할 수 있습니다.

if (updateInfo.isNeeded) {
  Alert.alert(
    '필수 업데이트',
    '중요 업데이트가 있습니다. 업데이트 후 사용이 가능합니다.',
    [
      {
        text: '업데이트',
        onPress: async () => {
          try {
            const storeUrl = updateInfo.storeUrl || await VersionCheck.getStoreUrl({ provider: 'playStore' });
            Linking.openURL(storeUrl);
          } catch (error) {
            console.error('스토어 URL 열기 실패:', error);
          }
        }
      }
    ],
    { cancelable: false } // 사용자가 취소할 수 없음
  );
}

 

커스텀 업데이트 UI

기본 Alert 대신 react-native-modal과 같은 라이브러리를 활용하여 Alert창이 아닌 직접 커스텀 업데이트 팝업을 구성할 수 있습니다.

import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Linking } from 'react-native';
import Modal from 'react-native-modal';
import VersionCheck from 'react-native-version-check';

const UpdateModal = ({ isVisible, onUpdatePress }) => (
  <Modal isVisible={isVisible}>
    <View style={styles.modalContainer}>
      <Text style={styles.modalTitle}>새로운 업데이트가 있습니다!</Text>
      <Text style={styles.modalMessage}>
        최신 기능 및 개선사항을 위해 업데이트를 진행해 주세요.
      </Text>
      <TouchableOpacity style={styles.updateButton} onPress={onUpdatePress}>
        <Text style={styles.updateButtonText}>업데이트 하기</Text>
      </TouchableOpacity>
    </View>
  </Modal>
);

const App = () => {
  const [isModalVisible, setModalVisible] = useState(false);

  useEffect(() => {
    const checkForUpdate = async () => {
      try {
        const currentVersion = VersionCheck.getCurrentVersion();
        const latestVersion = await VersionCheck.getLatestVersion({ provider: 'playStore' });
        const updateInfo = await VersionCheck.needUpdate({
          provider: 'playStore',
          depth: 2  // 마이너 버전 기준 비교
        });

        if (updateInfo.isNeeded) {
          setModalVisible(true);
        }
      } catch (error) {
        console.error('업데이트 확인 중 에러:', error);
      }
    };

    checkForUpdate();
  }, []);

  const handleUpdatePress = async () => {
    try {
      const storeUrl = await VersionCheck.getStoreUrl({ provider: 'playStore' });
      Linking.openURL(storeUrl);
    } catch (error) {
      console.error('스토어 URL 열기 실패:', error);
    }
  };

  return (
     <UpdateModal isVisible={isModalVisible} onUpdatePress={handleUpdatePress} />
  );
};

const styles = StyleSheet.create({
  modalContainer: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    alignItems: 'center'
  },
  modalTitle: { fontSize: 20, fontWeight: 'bold', marginBottom: 10 },
  modalMessage: { fontSize: 16, textAlign: 'center', marginBottom: 20 },
  updateButton: {
    backgroundColor: '#007AFF',
    paddingVertical: 10,
    paddingHorizontal: 20,
    borderRadius: 5
  },
  updateButtonText: { color: 'white', fontSize: 16 }
});

export default App;


5. 세부 메서드 설명 및 시멘틱 버저닝

getLatestVersion() 메서드

설명: 스토어(PlayStore 또는 App Store)에 등록된 최신 버전을 반환합니다.

옵션

• provider: 기본적으로 현재 플랫폼에 맞는 스토어에서 버전을 가져오며, ‘appStore’ 또는 ‘playStore’ 값을 지정하거나 사용자                     정의 함수를 제공할 수 있습니다.
• forceUpdate: 강제 업데이트 여부를 지정합니다.
• fetchOptions: 커스텀 API 호출 시 옵션 지정
• ignoreErrors: 에러 발생 시 무시할지 여부

 

예제) 사용자 정의 API를 통해 최신 버전을 가져오는 경우

VersionCheck.getLatestVersion({
  forceUpdate: true,
  provider: () =>
    fetch('http://your.own/api')
      .then(r => r.json())
      .then(({ version }) => version)
}).then(latestVersion => {
  console.log('내 API를 통한 최신 버전:', latestVersion);
});

 

needUpdate() 메서드

설명: 현재 버전과 최신 버전을 비교하여 업데이트 필요 여부를 판단합니다.

옵션

• currentVersion: 기본적으로 getCurrentVersion()을 통해 가져옴
• latestVersion: 스토어에서 가져온 최신 버전
• depth: 시멘틱 버저닝 기준 비교 깊이
• forceUpdate: 강제 업데이트 여부

 

예시)

현재 버전 1.0 vs 최신 버전 2.0 → 메이저 버전 변경 → 업데이트 필요

현재 버전 2.1 vs 최신 버전 2.0 (depth: 1) → 메이저 버전 비교 → 업데이트 불필요

// 예시: 현재 버전 2.1, 최신 버전 2.0 (메이저 버전 비교, depth: 1)
VersionCheck.needUpdate({
  depth: 1,
  currentVersion: "2.1",
  latestVersion: "2.0"
}).then(res => {
  console.log('업데이트 필요 여부:', res.isNeeded);  // false
});
반응형