문제 해결
react-native-coucon-sdk 사용 중 발생할 수 있는 오류와 해결 방법
문제 해결
자주 발생하는 오류
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'CouconSdk' could not be found
원인:
- 네이티브 모듈이 빌드에 포함되지 않음
- Expo Go에서 실행 시도
- iOS pod install 미실행
해결 방법:
-
Expo Go 대신 개발 빌드를 사용합니다:
npx expo run:ios# 또는npx expo run:android -
iOS에서 pod install을 실행합니다:
cd ios && pod install && cd .. -
Android에서 Gradle 동기화를 실행합니다:
cd android && ./gradlew build && cd .. -
Metro 캐시를 초기화하고 재시작합니다:
npx expo start --clear
run() 호출 후 이벤트가 수신되지 않음
원인:
run()호출 전에 리스너가 등록되지 않음subscription.remove()가 너무 일찍 호출됨initialize()가 호출되지 않은 상태에서run()실행
해결 방법:
올바른 호출 순서를 확인합니다:
// 1단계: 리스너 먼저 등록const subscription = addOnSASRunCompletedListener((event) => {console.log('결과 수신:', event);});// 2단계: SDK 초기화await initialize();// 3단계: SAS 실행await run(1, 'input');// 4단계: 결과 수신 후 정리 (너무 일찍 호출하지 않도록 주의)// subscription.remove(); // 결과를 다 받은 후 제거
subscription.remove()를 run() 직후 즉시 호출하면 비동기 이벤트를 수신하기 전에 리스너가 해제될 수 있습니다.
initialize() 실패 (false 반환)
원인:
- 네이티브 SAS 라이브러리 로드 실패
- 이미 초기화된 상태에서 충돌 발생 (드문 경우)
해결 방법:
const success = await initialize(true); // 디버그 모드로 상세 로그 확인if (!success) {// reset 후 재초기화 시도await reset(true);const retrySuccess = await initialize(true);console.log('재초기화 결과:', retrySuccess);}
메모리 누수 — 리스너가 정리되지 않음
원인: 컴포넌트 언마운트 후에도 subscription.remove()를 호출하지 않음
해결 방법:
React 컴포넌트에서는 반드시 useEffect cleanup에서 리스너를 제거합니다:
import { useEffect, useCallback } from 'react';import {initialize,run,addOnSASRunCompletedListener,} from '@boostbrothers/react-native-coucon-sdk';function CouconComponent() {const handleSasResult = useCallback((event) => {console.log('SAS 결과:', event.index, event.outString);}, []);useEffect(() => {let subscription;async function setup() {await initialize();subscription = addOnSASRunCompletedListener(handleSasResult);}setup();// cleanup: 컴포넌트 언마운트 시 자동 실행return () => {subscription?.remove();};}, [handleSasResult]);// ...}
여러 번 initialize() 호출 시 예기치 않은 동작
증상: 앱 내 여러 컴포넌트에서 initialize()를 각각 호출할 때 이상 동작
해결 방법:
앱 루트에서 한 번만 초기화합니다:
// app/_layout.tsx 또는 App.tsximport { useEffect } from 'react';import { initialize } from '@boostbrothers/react-native-coucon-sdk';export default function RootLayout() {useEffect(() => {initialize().catch(console.error);}, []);return <Stack />;}
개별 컴포넌트에서는 initialize()를 호출하지 않고 run()과 리스너만 사용합니다.
플랫폼별 이슈
iOS
빌드 오류: module 'CouconSdk' not found
pod install이 올바르게 실행되었는지 확인합니다. CouconSdk.podspec이 프로젝트에 포함되어야 합니다.
cd iospod deintegrate # 기존 pod 제거pod install # 재설치cd ..
Xcode 빌드 오류: 네이티브 라이브러리 링크 실패
Xcode의 Build Phases > Link Binary with Libraries에 Coucon 네이티브 라이브러리가 포함되어 있는지 확인합니다. pod install 후 .xcworkspace 파일로 프로젝트를 열고 있는지 확인합니다 (.xcodeproj 아님).
Android
빌드 오류: Could not find 'CouconSdk'
android/app/build.gradle에 모듈이 의존성에 포함되어 있는지 확인합니다. 자동 링킹이 정상적으로 작동하지 않는 경우 수동으로 패키지를 등록합니다.
New Architecture 활성화 필요
TurboModule을 사용하려면 android/gradle.properties에서 New Architecture가 활성화되어 있어야 합니다:
newArchEnabled=true
New Architecture를 비활성화한 상태에서는 모듈이 정상 동작하지 않을 수 있습니다.
디버깅 팁
디버그 모드 활성화
// 개발 중에는 디버그 모드를 사용하여 네이티브 로그 확인await initialize(true);await reset(true);
디버그 모드에서는 네이티브 레이어의 상세 로그가 Xcode Console (iOS) 또는 Logcat (Android)에 출력됩니다.
이벤트 수신 확인
const subscription = addOnSASRunCompletedListener((event) => {console.log('[CouconSdk] onSASRunCompleted:', JSON.stringify(event));});console.log('[CouconSdk] 리스너 등록 완료');await initialize(true);console.log('[CouconSdk] 초기화 완료');await run(1, 'test-input');console.log('[CouconSdk] run() 호출 완료 — 이벤트 대기 중...');
각 단계의 로그를 통해 어느 지점에서 문제가 발생하는지 파악할 수 있습니다.