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와 동일한 API를 제공하며, 플랫폼 차이만 내부적으로 처리합니다.
SDK 요청
React Native SDK는 별도 요청을 통해 제공됩니다. 담당자에게 문의하여 SDK 패키지를 받으세요.
요구사항
| 항목 | 버전 |
|---|---|
| React Native | >= 0.73 (0.76+ 권장) |
| React | >= 18 |
| react-native-agora | >= 4.3 (4.5+ 권장) |
| Expo | Development 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 installInfo.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:androidEAS Build를 사용하는 경우:
bash
eas build --profile development --platform ios # 또는 android3. 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" });
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-Talk) |
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 | 타입 | 기본값 | 설명 |
|---|---|---|---|
width | DimensionValue | - | 너비 (300 또는 "100%") |
height | DimensionValue | - | 높이 (400 또는 "100%") |
renderMode | "cover" | "contain" | "cover" | 비디오 fit 방식 |
borderRadius | number | 0 | 모서리 둥글기 |
초기화 옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
sdk_key | string | - | SDK 인증 키 (필수) |
avatar_id | string | - | 아바타 ID (필수) |
language | LanguageCode | "ko_kr" | TTS 언어 (ko_kr, en_us, ja_jp, id_id) |
log_level | LogLevel | "debug" | 로그 레벨 |
enable_microphone | boolean | true | 마이크 활성화 |
auto_send | boolean | false | true: VAD 자동 응답, false: Push-to-Talk |
stt_only | boolean | false | true: STT 결과만, false: STT + 아바타 응답 |
상태 흐름
IDLE → CONNECTING → SOCKET_CONNECTED → STREAMING_CONNECTED → CONNECTED_FINISH| 상황 | 흐름 |
|---|---|
| 정상 종료 | destroy() → IDLE |
| 에러 발생 | 자동 cleanup → 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() 재호출로 재연결 가능
});Push-to-Talk
tsx
<Pressable
onPressIn={() => KlleonSDK.startListening()}
onPressOut={() => KlleonSDK.endListening()}
>
<Text>길게 눌러서 말하기</Text>
</Pressable>에러 코드
| 코드 | 설명 |
|---|---|
SOCKET_FAILED | init 중 WebSocket 연결 실패 |
SOCKET_DISCONNECTED_UNEXPECTEDLY | 런타임 WebSocket 끊김 |
STREAMING_FAILED | init 중 Agora 연결 실패 |
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-ng | react-native-agora |
| UI | Lit 커스텀 엘리먼트 | KlleonAvatar 컴포넌트 |
| Hook | 없음 | useKlleonSDK |
| 설치 | <script> UMD | .tgz 파일 설치 |