Skip to content

React Native ​

Experimental

이 패키지는 실험 단계입니다. API가 예고 없이 변경될 수 있으며, 프로덕션 환경에서의 안정성이 보장되지 않습니다.

Expo Go / Snack 미지원

네이티브 모듈(react-native-agora)을 사용하므로 Expo Development Build (EAS Build 또는 로컬 빌드) 또는 bare workflow에서만 동작합니다. Expo Go와 Snack에서는 사용할 수 없습니다.

React Native용 Klleon AI 아바타 SDK (@klleon/sdk-rn)는 핵심 대화 흐름(연결 → 발화 → 응답)이 Web SDK와 같지만, 일부 메서드는 시그니처가 다릅니다. 네이티브 모듈 연동 같은 플랫폼 차이는 대부분 SDK 내부에서 처리하지만, 앱 코드에서 다르게 써야 하는 API는 아래 "Web SDK와의 차이"에 정리했습니다.

SDK 요청 ​

React Native SDK는 별도 요청을 통해 제공됩니다. 담당자에게 문의하여 SDK 패키지를 받으세요.

요구사항 ​

항목버전
React Native>= 0.73 (0.76+ 권장)
React>= 18
react-native-agora>= 4.3 (4.5+ 권장)
ExpoDevelopment Build 필수 (Expo Go / Snack 불가)

설치 ​

1. SDK 패키지 설치 ​

제공받은 .tgz 파일을 프로젝트 루트에 두고 설치합니다.

bash
# SDK 설치
npm install ./klleon-sdk-rn-x.x.x.tgz

# Agora 네이티브 모듈 설치
npm install react-native-agora

설치 후 package.json에 다음과 같이 추가됩니다:

json
{
  "dependencies": {
    "@klleon/sdk-rn": "file:klleon-sdk-rn-x.x.x.tgz",
    "react-native-agora": "^4.3.0"
  }
}

2. 플랫폼별 설정 ​

iOS ​

bash
cd ios && pod install

Info.plist에 마이크 권한 설명 추가:

xml
<key>NSMicrophoneUsageDescription</key>
<string>음성 대화를 위해 마이크 접근이 필요합니다.</string>

Android ​

android/app/src/main/AndroidManifest.xml에 권한 추가:

xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

Expo (Development Build) ​

Expo Go에서는 네이티브 모듈을 사용할 수 없으므로 Development Build가 필요합니다.

bash
# 네이티브 모듈 설치
npx expo install react-native-agora

# 네이티브 프로젝트 생성
npx expo prebuild

# 로컬 빌드 실행
npx expo run:ios   # 또는 npx expo run:android

EAS Build를 사용하는 경우:

bash
eas build --profile development --platform ios   # 또는 android

3. SDK 업데이트 ​

새 버전의 .tgz를 받으면 기존 파일을 교체하고 다시 설치합니다.

bash
npm install ./klleon-sdk-rn-x.x.x.tgz

빠른 시작 ​

tsx
import React, { useEffect } from "react";
import { View } from "react-native";
import { useKlleonSDK, KlleonAvatar } from "@klleon/sdk-rn";

export default function App() {
  const { status, init, destroy, sendMessage } = useKlleonSDK();

  useEffect(() => {
    init({ sdk_key: "YOUR_SDK_KEY", avatar_id: "YOUR_AVATAR_ID" }).catch(console.error);
    return () => { destroy(); };
  }, []);

  return (
    <View style={{ flex: 1 }}>
      <KlleonAvatar width="100%" height="100%" />
    </View>
  );
}

API ​

KlleonSDK (싱글톤) ​

typescript
import KlleonSDK from "@klleon/sdk-rn";
분류메서드설명
생명주기init(options)SDK 초기화 및 연결
destroy()SDK 종료 및 리소스 해제
콜백onSignal(cb)서버 시그널 수신
onStatus(cb)SDK 상태 변경
onError(cb)에러 발생
텍스트sendMessage(text)텍스트 전송 (LLM 응답 트리거)
speak(text)텍스트 에코 (아바타가 그대로 읽음)
오디오 립싱크 전송sendSpeakAudio(base64)Base64 오디오 전송
endSpeakAudio()오디오 립싱크 전송 종료
음성startListening()음성 입력 시작 (수동 전송, Push-to-Send)
endListening()음성 입력 종료
cancelListening()음성 입력 취소
아바타stopSpeaking()아바타 발화 중지
setVolume(0~100)아바타 음량 조절
조회getVersion()SDK 버전
getStatus()현재 상태
clearMessages()메시지 초기화

콜백은 init() 전에 등록 가능합니다.

useKlleonSDK (React Hook) ​

Valtio snapshot 기반으로 상태 변경 시 자동 리렌더링됩니다.

typescript
import { useKlleonSDK } from "@klleon/sdk-rn";

const {
  // 반응형 상태
  status, remoteUid, messages, signal,
  // 생명주기
  init, destroy,
  // 메서드
  sendMessage, speak, startListening, endListening, stopSpeaking, setVolume,
  // 콜백
  onSignal, onStatus, onError,
} = useKlleonSDK();

KlleonAvatar ​

아바타 비디오를 표시하는 컴포넌트입니다. SDK 연결 전에는 검정 배경을 표시합니다.

tsx
<KlleonAvatar width="100%" height={400} renderMode="cover" borderRadius={16} />
Prop타입기본값설명
widthDimensionValue-너비 (300 또는 "100%")
heightDimensionValue-높이 (400 또는 "100%")
renderMode"cover" | "contain""cover"비디오 fit 방식
borderRadiusnumber0모서리 둥글기

초기화 옵션 ​

옵션타입기본값설명
sdk_keystring-SDK 인증 키 (필수)
avatar_idstring-아바타 ID (필수)
languageLanguageCode"ko_kr"TTS 음성·자막 및 STT 인식 언어 (ko_kr, en_us, ja_jp, id_id)
log_levelLogLevel"warn"로그 레벨
enable_microphonebooleantrue마이크 활성화
auto_sendbooleanfalsetrue: VAD 자동 응답, false: 수동 전송
stt_onlybooleanfalsetrue: STT 결과만, false: STT + 아바타 응답

상태 흐름 ​

IDLE → CONNECTING → SOCKET_CONNECTED → STREAMING_CONNECTED → CONNECTED_FINISH
상황흐름
정상 종료destroy() → IDLE
에러 발생자동으로 연결 리소스 정리 → IDLE
재연결onError + onStatus(IDLE) 수신 후 init() 재호출

연동 예제 ​

권한 요청 (Android) ​

typescript
import { PermissionsAndroid } from "react-native";

await PermissionsAndroid.requestMultiple([
  PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
]);

에러 복구 ​

typescript
KlleonSDK.onError((error) => {
  console.log("SDK error:", error.code);
  // onStatus(IDLE)이 따라옴 → init() 재호출로 재연결 가능
});

수동 전송 ​

tsx
<Pressable
  onPressIn={() => KlleonSDK.startListening()}
  onPressOut={() => KlleonSDK.endListening()}
>
  <Text>길게 눌러서 말하기</Text>
</Pressable>

에러 코드 ​

초기화 실패는 에러 코드 없이 init()의 예외(reject)로 전달됩니다. 아래 코드는 연결 이후 런타임에 onError로 전달됩니다.

코드설명
SOCKET_DISCONNECTED_UNEXPECTEDLY런타임 WebSocket 끊김
STREAMING_DISCONNECTED_UNEXPECTEDLY런타임 Agora 끊김
SERVER_ERROR서버 에러 시그널
WORKER_DISCONNECTED워커 종료 시그널

타입 ​

typescript
// Enum
import { SDKStatus, ErrorCode, IncomingSignal, OutgoingSignal } from "@klleon/sdk-rn";

// Type
import type {
  InitOption, IncomingSignalData, OutgoingSignalData,
  ErrorData, MessageItem, LogLevel, LanguageCode,
} from "@klleon/sdk-rn";

Web SDK와의 차이 ​

항목Web (sdk-klleon)RN (sdk-rn)
비디오agora-rtc-sdk-ngreact-native-agora
speak 시그니처speak(문자열 또는 옵션 객체)speak(문자열)만 지원
UILit 커스텀 엘리먼트KlleonAvatar 컴포넌트
Hook없음useKlleonSDK
설치<script> UMD.tgz 파일 설치
아바타 렌더링 API<avatar-container> 엘리먼트 배치 (fit)KlleonAvatar 컴포넌트 (width, height, renderMode, borderRadius)
상태 구독 APIonStatus / onSignal 콜백onStatus / onSignal 콜백 + useKlleonSDK (status, remoteUid, messages, signal)