본문 바로가기

React Native

React Native에서 커스텀 네이티브 모듈 만들기

반응형

React Native로 커스텀 네이티브 모듈을 만들고 사용하는 방법을 단계별로 알아보겠습니다. 네이티브 기능을 JavaScript로 연결하여 성능을 높이고, 사용자 경험을 확장하는 방법을 설명합니다.

 

커스텀 네이티브 모듈이란?

커스텀 네이티브 모듈의 개념과 필요성

React Native는 JavaScript로 네이티브 모바일 애플리케이션을 개발할 수 있는 훌륭한 프레임워크입니다. 하지만 간혹 JavaScript만으로는 해결하기 어려운 네이티브 기능이 필요할 때가 있습니다. 이때 커스텀 네이티브 모듈을 제작하여 JavaScript에서 사용할 수 있게 하면 성능을 개선하고, 기존 네이티브 코드와 통합할 수 있는 강력한 도구를 갖추게 됩니다. 예를 들어, GPS 데이터 수집이나 센서 데이터 접근처럼 네이티브 수준의 권한이 필요한 경우 커스텀 모듈을 이용하면 유용합니다.

React Native와 네이티브 간의 통신 방식 이해하기

React Native는 JavaScript와 네이티브 코드(Android의 Java, iOS의 Swift/Objective-C) 간에 브릿지를 통해 데이터를 주고받습니다. 이 브릿지는 양방향 통신을 가능하게 해 주며, 커스텀 모듈을 제작할 때 이 브릿지를 활용하게 됩니다. 이 점을 이해하면, JavaScript 코드에서 네이티브 기능을 호출하거나 네이티브 코드에서 JavaScript 이벤트를 발생시키는 과정을 보다 쉽게 파악할 수 있습니다.

 

프로젝트 설정

Android 스튜디오와 Xcode 설치

커스텀 네이티브 모듈을 제작하려면 Android와 iOS의 네이티브 개발 환경이 필요합니다. Android용으로는 Android 스튜디오, iOS용으로는 Xcode가 필요하며, 이를 통해 각각의 플랫폼에서 모듈을 작성하고 디버깅할 수 있습니다. React Native CLI를 사용하여 프로젝트를 생성하는 것도 권장됩니다. 이렇게 해야 네이티브 파일 접근이 더욱 용이해집니다.

React Native 프로젝트에 네이티브 모듈 추가하기

React Native 프로젝트를 생성한 후, android와 ios 디렉토리 내에서 각각의 네이티브 모듈 파일을 추가해야 합니다. 이 과정에서 네이티브 모듈을 JavaScript로 연결할 수 있는 기본적인 틀을 마련하게 됩니다. 이후 각 플랫폼에 맞는 설정을 진행합니다.

 

Android용 커스텀 네이티브 모듈 제작

Android 모듈 설정과 Java 코드 작성

Android에서는 Java 또는 Kotlin을 사용하여 네이티브 모듈을 작성합니다. 예를 들어, Android 스튜디오에서 MyCustomModule.java 파일을 생성하고, React Native에 이 모듈을 등록합니다. 다음은 기본적인 구조입니다.

package com.myapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

public class MyCustomModule extends ReactContextBaseJavaModule {
	public MyCustomModule(ReactApplicationContext reactContext) {
		super(reactContext);
	}

	@Override
	public String getName() {
		return "MyCustomModule";
	}

	@ReactMethod
	public void getDeviceName(Promise promise) {
		try {
			String deviceName = android.os.Build.MODEL;
			promise.resolve(deviceName);
		} catch (Exception e) {
			promise.reject("Error", e);
		}
	}
}

 

이 코드에서 getDeviceName 메서드는 장치의 이름을 반환합니다. Promise 객체를 사용하여 JavaScript로 결과를 전달할 수 있습니다.

@ReactMethod와 Promise 사용하기

@ReactMethod는 네이티브 모듈 내에서 JavaScript에서 호출 가능한 메서드를 정의할 때 사용하는 애노테이션입니다. 이를 통해 특정 메서드를 JavaScript에서 직접 접근할 수 있게 됩니다. 위 코드에서 getDeviceName 메서드에 @ReactMethod를 붙임으로써, React Native는 이 메서드를 브릿지를 통해 JavaScript로 노출시킵니다.

 

이와 함께 Promise 객체를 사용하는데, 이는 JavaScript와 비동기적으로 통신하기 위해 사용됩니다. Promise.resolve()와 Promise.reject()를 통해 작업이 성공했는지 실패했는지 JavaScript에 알릴 수 있습니다. 이렇게 하면 네이티브 기능이 완료될 때 JavaScript에서 이를 처리할 수 있습니다.

JavaScript에서 Android 모듈 연결하기

Java 코드를 작성한 후에는 JavaScript에서 이를 불러와 사용할 수 있도록 해야 합니다. 이를 위해 NativeModules를 이용합니다.

import { NativeModules } from 'react-native';
const { MyCustomModule } = NativeModules;

MyCustomModule.getDeviceName()
	.then((deviceName) => console.log(deviceName))
	.catch((error) => console.error(error));

 

이렇게 하면 Java에서 작성한 getDeviceName 메서드를 JavaScript에서 호출할 수 있습니다.

 

iOS용 커스텀 네이티브 모듈 제작

Xcode를 이용한 iOS 모듈 설정

iOS에서는 Xcode를 이용하여 네이티브 모듈을 작성합니다. MyCustomModule.m 파일을 생성하고 Objective-C로 모듈을 작성하거나, Swift로 작성할 수도 있습니다.

Objective-C/Swift로 iOS 모듈 작성하기

Objective-C를 사용하여 간단한 모듈을 작성하는 예시는 다음과 같습니다.

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(MyCustomModule, NSObject)

RCT_EXTERN_METHOD(getDeviceName:(RCTPromiseResolveBlock)resolve
	rejecter:(RCTPromiseRejectBlock)reject)
    
@end

 

물론 Swift로도 작성할 수 있습니다.

import Foundation
import React

@objc(MyCustomModule)
class MyCustomModule: NSObject {
	@objc
	static func requiresMainQueueSetup() -> Bool {
		return false
	}
    
	@objc
	func getDeviceName(_ resolve: @escaping RCTPromiseResolveBlock,
						rejecter reject: @escaping RCTPromiseRejectBlock) {
		let deviceName = UIDevice.current.name
 		resolve(deviceName)
	}
}

 

이 모듈은 Android와 마찬가지로 장치의 이름을 가져오는 기능을 제공합니다.

RCT_EXTERN_METHOD로 모듈 정의하기

RCT_EXTERN_METHOD는 Objective-C에서 네이티브 메서드를 JavaScript에 노출시키기 위해 사용됩니다. 이 매크로를 사용하여 iOS 네이티브 코드에서 특정 메서드를 JavaScript에서 접근 가능하도록 만듭니다. 예를 들어, 위 코드에서 getDeviceName 메서드는 RCT_EXTERN_METHOD를 통해 정의되어 JavaScript에서 호출될 수 있습니다.

 

RCTPromiseResolveBlock과 RCTPromiseRejectBlock은 각각 작업이 성공했을 때와 실패했을 때 호출하는 콜백으로, JavaScript에서 이를 비동기적으로 처리할 수 있도록 해줍니다.

JavaScript와 iOS 모듈 통합하기

JavaScript에서 iOS 모듈을 불러오는 방식은 Android와 동일합니다. NativeModules를 사용하여 iOS 네이티브 모듈을 호출할 수 있습니다.

import { NativeModules } from 'react-native';
const { MyCustomModule } = NativeModules;

MyCustomModule.getDeviceName()
	.then((deviceName) => console.log(deviceName))
	.catch((error) => console.error(error));

 

JavaScript에서 네이티브 모듈 사용하기

모듈 메서드 호출 및 결과 처리

JavaScript에서 네이티브 모듈의 메서드를 호출하면, 네이티브에서 반환된 값을 Promise로 처리할 수 있습니다. 이를 통해 비동기 작업도 간편하게 다룰 수 있습니다. 네이티브 모듈은 대부분 비동기 작업을 수행하므로, then이나 catch를 사용하여 결과를 처리합니다.

네이티브 모듈의 비동기 작업 다루기

네이티브 모듈은 대부분 비동기 작업을 수행하기 때문에, JavaScript에서는 async/await 구문을 사용하여 더 직관적으로 코드를 작성할 수 있습니다.

async function fetchDeviceName() {
	try {
		const deviceName = await MyCustomModule.getDeviceName();
		console.log(deviceName);
	} catch (error) {
		console.error(error);
	}
}

 

이렇게 하면 네이티브 모듈과의 통신을 더욱 간단하게 처리할 수 있습니다.

 

모듈 테스트 및 디버깅

Android와 iOS에서 모듈 테스트하기

각 플랫폼에서 네이티브 모듈이 제대로 작동하는지 확인하려면 실제 디바이스나 에뮬레이터에서 테스트를 진행해야 합니다. Android 스튜디오와 Xcode의 디버깅 도구를 활용하면 오류를 쉽게 찾고 수정할 수 있습니다. 특히, 네이티브 모듈의 로직이 제대로 실행되는지, JavaScript와의 통신에 문제가 없는지 확인하는 것이 중요합니다.

오류 해결 및 디버깅 팁

가장 흔한 문제는 네이티브 모듈이 JavaScript에서 인식되지 않는 것입니다. 이는 네이티브 모듈이 제대로 등록되지 않았거나 빌드 설정이 올바르지 않을 때 발생할 수 있습니다. 빌드가 실패하는 경우, 로그를 통해 문제의 원인을 파악하고 수정하는 것이 중요합니다. Android의 Logcat과 Xcode의 콘솔을 활용하면 문제를 보다 효율적으로 해결할 수 있습니다.

 

마무리하며

React Native로 커스텀 네이티브 모듈을 만드는 것은 앱의 기능을 확장하고 성능을 개선하는 데 매우 유용합니다. 네이티브 플랫폼의 고유 기능을 JavaScript에서 접근할 수 있도록 만들어 주기 때문에, 개발자가 맞춤형 기능을 구현하고자 할 때 강력한 도구가 됩니다. 위에서 소개한 Android와 iOS의 네이티브 모듈 제작 방법을 따라가면, 다양한 요구사항에 대응할 수 있는 커스텀 기능을 앱에 추가할 수 있을 것입니다.

반응형