Skip to main content
Version: Next

플랫폼별 코드

크로스 플랫폼 앱을 개발할 때는 가능한 한 많은 코드를 재사용하는 것이 중요하다. 하지만 특정 상황에서는 플랫폼마다 코드가 달라야 할 수도 있다. 예를 들어, Android와 iOS에 대해 서로 다른 시각적 컴포넌트를 구현해야 할 수 있다.

React Native는 코드를 조직하고 플랫폼별로 분리하는 두 가지 방법을 제공한다:

일부 컴포넌트는 특정 플랫폼에서만 작동하는 속성을 가질 수 있다. 이러한 속성은 @platform으로 주석 처리되며, 웹사이트에서는 작은 배지로 표시된다.

플랫폼 모듈

React Native는 앱이 실행 중인 플랫폼을 감지하는 모듈을 제공한다. 이 감지 로직을 사용해 플랫폼에 특화된 코드를 구현할 수 있다. 컴포넌트의 일부만 플랫폼에 따라 다를 때 이 옵션을 사용한다.

tsx
import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
height: Platform.OS === 'ios' ? 200 : 100,
});

Platform.OS는 iOS에서 실행 중일 때 ios를, Android에서 실행 중일 때 android를 반환한다.

또한 Platform.select 메서드를 사용할 수 있다. 이 메서드는 'ios' | 'android' | 'native' | 'default' 중 하나를 키로 가지는 객체를 인자로 받아 현재 실행 중인 플랫폼에 가장 적합한 값을 반환한다. 즉, 휴대폰에서 실행 중이라면 iosandroid 키가 우선순위를 가진다. 이 키들이 지정되지 않았다면 native 키가 사용되고, 그다음 default 키가 사용된다.

tsx
import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'green',
},
default: {
// 다른 플랫폼, 예를 들어 웹
backgroundColor: 'blue',
},
}),
},
});

이 코드는 모든 플랫폼에서 flex: 1을 가지는 컨테이너를 생성한다. iOS에서는 빨간 배경색, Android에서는 초록 배경색, 다른 플랫폼에서는 파란 배경색을 적용한다.

이 메서드는 any 타입의 값을 받기 때문에 아래와 같이 플랫폼에 특화된 컴포넌트를 반환하는 데에도 사용할 수 있다.

tsx
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();

<Component />;
tsx
const Component = Platform.select({
native: () => require('ComponentForNative'),
default: () => require('ComponentForWeb'),
})();

<Component />;

안드로이드 버전 감지하기
Android

안드로이드에서는 Platform 모듈을 사용해 앱이 실행 중인 안드로이드 플랫폼의 버전을 감지할 수 있다:

tsx
import {Platform} from 'react-native';

if (Platform.Version === 25) {
console.log('Running on Nougat!');
}

참고: Version은 안드로이드 OS 버전이 아닌 안드로이드 API 버전을 나타낸다. 매핑 정보는 안드로이드 버전 히스토리를 참고한다.

iOS 버전 감지하기
iOS

iOS에서는 Version-[UIDevice systemVersion]의 결과로, 현재 운영체제의 버전을 나타내는 문자열이다. 시스템 버전의 예로는 "10.3"이 있다. 예를 들어, iOS의 주요 버전 번호를 감지하려면 다음과 같이 코드를 작성한다:

tsx
import {Platform} from 'react-native';

const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('동작 변경에 대한 해결책을 적용한다');
}

플랫폼별 확장 기능

플랫폼별 코드가 복잡해지면, 코드를 별도의 파일로 분리하는 것을 고려해야 한다. React Native는 파일 이름에 .ios. 또는 .android. 확장자가 붙은 파일을 자동으로 감지하고, 필요할 때 해당 플랫폼에 맞는 파일을 로드한다.

예를 들어, 프로젝트에 다음과 같은 파일이 있다고 가정해 보자:

shell
BigButton.ios.js
BigButton.android.js

그러면 컴포넌트를 다음과 같이 임포트할 수 있다:

tsx
import BigButton from './BigButton';

React Native는 실행 중인 플랫폼에 따라 적절한 파일을 자동으로 선택한다.

네이티브 전용 확장 (NodeJS와 웹 간 코드 공유)

모듈을 NodeJS/웹과 React Native 간에 공유해야 하지만 Android/iOS 차이가 없는 경우 .native.js 확장자를 사용할 수 있다. 이 방법은 React Native와 ReactJS 간에 공통 코드를 공유하는 프로젝트에 특히 유용하다.

예를 들어, 프로젝트에 다음과 같은 파일이 있다고 가정해 보자:

shell
Container.js # 웹팩, 롤업 또는 기타 웹 번들러가 선택
Container.native.js # Android와 iOS 모두에서 React Native 번들러(Metro)가 선택

.native 확장자 없이도 다음과 같이 모듈을 가져올 수 있다:

tsx
import Container from './Container';

팁: 프로덕션 번들에 사용되지 않는 코드를 포함하지 않도록 웹 번들러가 .native.js 확장자를 무시하도록 설정하면 최종 번들 크기를 줄일 수 있다.