React Native in Android #4

React 를 쓰는 가장 큰 이유인, 앱 스토어 릴리즈 없이 기능 업데이트를 위해 Microsoft 의 CodePush 서비스를 사용해 보겠습니다.

CodePush CLI 부터 설치해 볼까요.

npm 을 통해 설치 합니다.

npm install -g code-push-cli

CodePush 계정을 생성합니다.

GitHub 계정을 먼저 생성합니다. 이후 콘솔에서 아래와 같이 입력하면 브라우저가 열리면서 Access Key 를 받을 수 있습니다.

code-push register

CodePush 에 앱을 등록합니다.

이전에 만들었던 AwesomeProject 앱을 등록합니다. iOS / Android 별로 bundle 을 만들어야 하기 때문에 프로젝트 명을 다르게 등록해야 합니다.

code-push app add AwesomeProject

React Native Module 을 설치합니다.

프로젝트 폴더로 이동한 후 npm 을 통해 설치합니다. Deployment Key 는 Production 으로 등록합니다. 일단 iOS 는 무시합니다. latest 는 현재 2.0.2-beta 입니다.

npm install --save react-native-code-push@latest
react-native link react-native-code-push

android/settings.gradle 에 아래 내용이 추가 되었는지 확인 합니다. 특히 경로에 주의해야 합니다.

include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

android/app/build.gradle 에 아래 내용이 추가 되었는지 확인 합니다.

apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
buildTypes {
debug {
buildConfigField "String", "CODEPUSH_KEY", "\"Staging Deployment Key\""
...
}
release {
buildConfigField "String", "CODEPUSH_KEY", "\"Production Deployment Key\""
...
}
}
dependencies {
...
compile project(':react-native-code-push')
}
settings.gradle 에 있는 projectDir 기준으로 상대 경로를 build.gradle 에 각각 설정해 줘야 합니다. 특히 node module 을 추가하여 link 할 때 gradle 설정이 필요한 경우, React Native 버젼 관리할 때 꼭 확인해서 적용해야 합니다.

ReactApplication 을 상속받은 MainApplication 에 아래 내용이 추가 되었는지 확인 합니다. strings.xml 에 Deployment Key 관련 내용은 삭제합니다.

@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new CodePush(
BuildConfig.CODEPUSH_KEY,
getApplicationContext(),
BuildConfig.DEBUG)
);
}

gradle 빌드를 하면서 react-native 와 버젼 충돌이 있는 경우, Supported React Native platforms 을 참고하셔서 버젼 설정을 해야 합니다.

com.android.support 버젼 관리는 react-native 에서도 사용하기 때문에, 같이 버젼 관리를 해줘야 합니다만, react-native 에서 해당 버젼을 수정하는 부분을 아직 찾지 못했습니다. 일단 com.android.support 버젼은 react-native 의 AwesomeProject 예제와 동일한 버젼으로 작업하도록 합니다.

Fragment 레벨에서 ReactInstanceManager 를 통해 처리할 수도 있습니다.

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
  ReactPackage codepush = new CodePush(BuildConfig.CODEPUSH_KEY, getActivity(), false);
self.reactInstanceManager = ReactInstanceManager.builder()
.setApplication(getActivity().getApplication())
.setJSBundleFile(CodePush.getJSBundleFile())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(codepush)
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
  ...
}

Component 에 Code Push 를 위한 기능을 추가합니다.

Component 에 Code Push 를 통해 언제 bundle 확인을 할건지 설정하고, 각 단계별 인터페이스를 구현합니다. index.android.js 에 아래와 같이 추가합니다.

...
import codePush from "react-native-code-push";
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
...
codePushStatusDidChange(status) {
switch(status) {
case codePush.SyncStatus.CHECKING_FOR_UPDATE:
console.log("Checking for updates.");
break;
case codePush.SyncStatus.DOWNLOADING_PACKAGE:
console.log("Downloading package.");
break;
case codePush.SyncStatus.INSTALLING_UPDATE:
console.log("Installing update.");
break;
case codePush.SyncStatus.UP_TO_DATE:
console.log("Up-to-date.");
break;
case codePush.SyncStatus.UPDATE_INSTALLED:
console.log("Update installed.");
break;
}
}
codePushDownloadDidProgress(progress) {
console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
}
AwesomeProject = codePush(codePushOptions)(AwesomeProject);

관련 옵션들이 많은데요. Code Push 문서를 참고해 주세요.

Code Push 에 bundle 을 생성하여 release 합니다.

위에서 변경된 내용을 adb 를 통해 테스트를 한 후에, 터미널에서 아래와 같이 release 합니다. deployment 정보도 확인 할 수 있습니다.

code-push release-react AwesomeProject android
code-push deployment ls AwesomeProject --displayKeys

Javascript 코드를 변경하고 release 합니다.

테스트 기기의 usb 케이블을 빼고, Javascript 코드를 변경한 후, 다시 릴리즈 하여 앱 업데이트 없이 되는지 확인합니다.

adb 를 사용하는 경우, Android Studio 에서 빌드하지 말고, 아래 명령어를 통해 빌드하는 걸 추천합니다.

react-native run-android --main-activity .MainActivity

Code Push 의 bundle 을 Production 으로 올립니다.

Code Push 에 업로드된 bundle 을 staging 에서 production 으로 이동하기 위해서, 아래와 같이 입력합니다.

code-push promote AwesomeProject Staging Production

Release apk 를 테스트 합니다.

Release 로 build 하고 테스트하기 위해 아래와 같이 입력합니다.

react-native run-android --main-activity .MainActivity --variant=release
code-push deployment ls AwesomeProject --displayKeys