Native Modules를 사용하면 JavaScript에서 접근할 수 없는 플랫폼 고유 API를 직접 호출할 수 있습니다.

React Native가 제공하지 않는 네이티브 기능(결제 SDK, 하드웨어 센서, 플랫폼 전용 API 등)이 필요할 때 Native Module을 작성합니다.


iOS Native Module (Swift)

SWIFT
// ios/BatteryModule.swift
import Foundation

@objc(BatteryModule)
class BatteryModule: NSObject {

  @objc
  func getBatteryLevel(_ resolve: @escaping RCTPromiseResolveBlock,
                        rejecter reject: @escaping RCTPromiseRejectBlock) {
    UIDevice.current.isBatteryMonitoringEnabled = true
    let level = UIDevice.current.batteryLevel
    if level < 0 {
      reject("ERROR", "배터리 레벨을 읽을 수 없습니다", nil)
    } else {
      resolve(level * 100)
    }
  }

  @objc
  static func requiresMainQueueSetup() -> Bool {
    return false
  }
}
OBJC
// ios/BatteryModule.m (브릿지 헤더)
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(BatteryModule, NSObject)
RCT_EXTERN_METHOD(getBatteryLevel:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
@end

Android Native Module (Kotlin)

KOTLIN
// android/app/src/main/java/com/myapp/BatteryModule.kt
package com.myapp

import android.os.BatteryManager
import android.content.Context
import com.facebook.react.bridge.*

class BatteryModule(reactContext: ReactApplicationContext)
  : ReactContextBaseJavaModule(reactContext) {

  override fun getName() = "BatteryModule"

  @ReactMethod
  fun getBatteryLevel(promise: Promise) {
    val batteryManager = reactApplicationContext
      .getSystemService(Context.BATTERY_SERVICE) as BatteryManager
    val level = batteryManager.getIntProperty(
      BatteryManager.BATTERY_PROPERTY_CAPACITY
    )
    promise.resolve(level)
  }
}
KOTLIN
// BatteryPackage.kt — 모듈 등록
package com.myapp

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

class BatteryPackage : ReactPackage {
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
    return listOf(BatteryModule(reactContext))
  }
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
    return emptyList()
  }
}

JavaScript에서 사용

TSX
import { NativeModules } from 'react-native';

const { BatteryModule } = NativeModules;

async function checkBattery() {
  try {
    const level = await BatteryModule.getBatteryLevel();
    console.log(`배터리: ${level}%`);
  } catch (error) {
    console.error('배터리 확인 실패:', error);
  }
}

네이티브 이벤트 전송

SWIFT
// iOS — 이벤트 발송
@objc(BatteryModule)
class BatteryModule: RCTEventEmitter {
  override func supportedEvents() -> [String]! {
    return ["onBatteryChange"]
  }

  func sendBatteryUpdate(level: Float) {
    sendEvent(withName: "onBatteryChange", body: ["level": level])
  }
}
TSX
// JavaScript — 이벤트 수신
import { NativeEventEmitter, NativeModules } from 'react-native';

const { BatteryModule } = NativeModules;
const emitter = new NativeEventEmitter(BatteryModule);

useEffect(() => {
  const subscription = emitter.addListener('onBatteryChange', (event) => {
    console.log('배터리 변경:', event.level);
  });
  return () => subscription.remove();
}, []);

정리

  • Native Module은 JavaScript Bridge를 통해 네이티브 코드를 호출 합니다
  • iOS는 Swift/Objective-C, Android는 Kotlin/Java로 작성합니다
  • 비동기 작업 은 Promise 패턴으로, 실시간 알림 은 EventEmitter로 처리합니다
  • 새 아키텍처(Turbo Modules)로 전환하면 Bridge 없이 직접 호출이 가능해집니다
  • 대부분의 네이티브 기능은 커뮤니티 라이브러리 가 이미 존재하니 먼저 검색하세요
댓글 로딩 중...