---
# System prepended metadata

title: Android와 Ios
tags: [reactnative배포]

---

---
tags: reactnative배포
---

# Android와 Ios

웹 서비스의 경우 웹서버에 화면에 필요한 html, js, css등의 정적파일을 브라우저를 통해 요청하고 브라우저가 해당 파일을 해석하여 화면을 그리지만 어플리케이션은 디바이스에 적절한 파일이 설치되어 각 플랫폼에서 실행되어야합니다.

리엑트 네이티브(react-native)를 통해 개발한 어플리케이션은 각각 android, ios용 어플리케이션으로 빌드되어 플레이스토어와 앱스토어에 출시됩니다.

각각의 개발 소스는 리엑트 네이티브상의 JS코드로 작업하지만 실질적인 빌드작업은 Android와 Ios의 빌드 파이프라인을 따라서 동작합니다.

이번 글은 그 시스템을 간단히 알아보고 정리하는 과정을 가져봅시다.

## Android

안드로이드는 Gradle을 사용하여 어플리케이션을 빌드합니다. 생성된 리엑트 네이티브 프로젝트의 `android` 디렉토리를 살펴보면 관련된 파일들을 확인할 수있습니다.

![](https://i.imgur.com/haayXG6.png)

모든 파일을 파악하고 있으면 좋지만 몇몇개만 우선적으로 파악해봅시다.

**gradle 디렉토리내의 wrapper**는 gradle을 사용할 수 있도록 도와주는 tool로 gradle 바이너리를 빌드시 적절히 다운로드 받게 합니다. gradle의 버전을 직접적으로 관리하므로 `gradle wrapper`를 통해 gradle의 버전을 관리할 수 있습니다.

예를 들어 gradle의 버전을 7.5.1로 바꾸려면 아래 명령어를 실행할 수 있습니다.

```bash
./gradle wrapper --gradle-version --7.5.1
```

root의 `build.gradle`은 직접적인 빌드 스크립트 파일로 모든 모듈에 공통으로 적용해야하는 사항들을 적어넣습니다. 예를 들면 빌드에 포함시킬 SDK버전이나 AGP(android gradle plugin) 디펜던시 등을 포함합니다.

app의 `build.gradle`또한 빌드 스크립트로 해당 앱(모듈)을 빌드할때 적용할 사항을 적어넣습니다. 이곳에는 빌드에대한 환경이나 어플리케이션 버전등의 정보를 포함합니다.

### build.gradle 살펴보기

gradle은 build.gradle을 통해 빌드를 실행하므로 build.gradle을 간단히 살펴보겠습니다.

```groovy
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'

android {
   ...   
}
```

플러그인 설정 하는 과정입니다.


## Ios



### 여담: 실제로 발생했던 이슈에 대해

Android 버전이 13으로 올라갈 때(22.8), Android 정책 중 POST_NOTIFICATIONS에 대한 정책이 추가되었습니다. 기존에는 어플리케이션들이 알림(notifications)에 대한 권한이 모두 **"허용상태"** 로 다운로드 되었으나 13버전 기준 모든 어플리케이션은 다운로드시 알림권한이 **"비허용"** 상태이며 알림 권한(permission)이 요청을 받아야합니다.

이에 안드로이드는 이를 요청하기위해 POST_NOTIFIACTIONS 퍼미션 요청을 추가함에 따라 sdk 빌드 타겟을 33으로 올려야 했습니다.

필요한 작업은 아래와 같았습니다.

기존 타겟이 31버전임에 따라 해당 과정에서 root의 `build.gradle`의 타겟을 아래와 같이 수정했습니다.

```groovy
buildscript {
    ext {
        // buildToolsVersion = "31.0.0"
        buildToolsVersion = "33.0.1"
        minSdkVersion = 24
        //compileSdkVersion = 31
        compileSdkVersion = 33
        // targetSdkVersion = 31
        targetSdkVersion = 33
        kotlinVersion = "1.5.20"
      }
  ...
}
```

이참에 기존에 gradle을 7.0.2 버전, AGP(android gradle plugin)을 7.0.1로 관리하였으므로 해당 버전을 7.5.1, 7.3.3으로 변경하였습니다.

```bash
./gradle wrapper --gradle-version --7.5.1
```

```groovy
buildscript {
    ...
    dependencies {
      ...
      classpath("com.android.tools.build:gradle:7.3.1") 
    }
}
```

이후 발생한 react-native-gesture-handler 버전 문제, react-native-web-view 버전 문제 등 자잘한 마이그레이션 문제가 발생했으나 이 부분은 생략합니다.

debug후 테스트용 릴리즈를 배포했을 때 앱이 켜지지 않고 터지는 문제가 발생했습니다.

firebase crashlytics가 보여준 에러는 아래와 같았습니다.

```
Unable to load script. Make sure you're either running Metro (run 'npx react-native start') or that your bundle 'index.android.bundle' is packaged correctly for release.
```

원인은 react-native(0.66)가 지원하는 AGP버전과의 호환성 문제였고 최신 버전 AGP가 아닌 레거시 AGP(7.0.4)로 변경 후 정상작동 되었습니다.

```groovy
buildscript {
    ...
    dependencies {
      ...
      classpath("com.android.tools.build:gradle:7.0.4") 
    }
}
```
