AI 모델은 매우 크기 때문에 네이티브 React Native 다운로더를 만들었습니다
요약
대용량 AI 모델 파일을 안정적으로 다운로드하기 위한 React Native용 네이티브 HTTP 클라이언트 패키지인 'react-native-client'를 소개합니다. 네트워크 중단이나 앱 종료 시에도 HTTP Range 요청을 통해 다운로드를 이어받을 수 있는 기능을 제공합니다.
핵심 포인트
- JavaScript 브릿지를 거치지 않고 네이티브 측에서 디스크로 직접 스트리밍
- Android(OkHttp) 및 iOS(URLSession) 네이티브 API 활용
- HTTP Range 요청을 통한 이어받기(Resumable downloads) 지원
- 백그라운드 다운로드를 위한 포그라운드 서비스 및 백그라운드 URLSession 지원
저는 Android용 프라이빗 오프라인 AI 앱인 Orb를 개발하면서 이 문제에 직면했습니다.
Orb는 휴대폰에서 로컬 모델 (local models)을 실행합니다. 이는 개인정보 보호 측면에서 매우 훌륭하지만, 매우 실질적인 모바일 문제를 야기합니다. 앱이 수 기가바이트(GB)에 달할 수 있는 모델 파일들을 다운로드해야 한다는 점입니다. 만약 네트워크가 끊기거나, 앱이 백그라운드로 전환되거나, 사용자가 앱을 강제 종료할 경우, 처음부터 다시 시작해야 하는 것은 끔찍한 경험입니다.
그래서 저는 다운로더 기능을 별도의 작은 오픈 소스 패키지로 분리했습니다:
GitHub: https://github.com/zraisan/react-native-client
NPM: https://www.npmjs.com/package/react-native-client
react-native-client는 JavaScript 브릿지 (JavaScript bridge)를 통해 바이트를 이동시키지 않고 파일로 직접 다운로드해야 하는 React Native 앱을 위한 네이티브 HTTP 클라이언트 (native HTTP client)입니다. 첫 번째 안정적인 API는 일반적인 HTTP 요청이 아닌 다운로드에 초점을 맞추고 있습니다.
기능
이 패키지는 Nitro Modules를 통해 타입이 지정된 downloadFile API를 노출합니다.
내부 동작 방식:
- Android는 OkHttp를 사용합니다.
- iOS는 URLSession을 사용합니다.
- 파일은 네이티브 측에서 디스크로 직접 스트리밍 (streamed) 됩니다.
- 진행 상황 콜백 (progress callbacks)은 기록된 바이트 수와 전체 길이를 보고합니다.
- 이어받기 가능한 다운로드 (resumable downloads)는 HTTP Range 요청을 사용합니다.
- 부분 파일 재개 (partial-file resume)는 추가하기 전에
Content-Range를 검증합니다. - Android 백그라운드 모드는 포그라운드 서비스 (foreground service)를 사용합니다.
- iOS는 백그라운드 URLSession 경로를 사용합니다.
주요 사용 사례는 대용량 파일입니다: AI 모델, 미디어 팩, 오프라인 데이터셋, 캐시 웜업 (cache warmups), 그리고 2GB 다운로드 실패가 처음부터 다시 시작하는 것을 의미해서는 안 되는 모든 것들입니다.
기본 사용법
import { downloadFile, documentDirectoryPath } from 'react-native-client'
const result = await downloadFile({
...
진행 상황 포함:
await downloadFile({
fromUrl: 'https://example.com/large-file.bin',
toFile: `${documentDirectoryPath}/large-file.bin`,
...
이어받기 가능한 백그라운드 다운로드:
await downloadFile({
fromUrl: 'https://example.com/model.gguf',
toFile: `${documentDirectoryPath}/model.gguf`,
...
앱 재실행 후 이어받기를 하려면, 동일한 toFile과 resumable: true 옵션을 사용하여 동일한 요청을 다시 호출하세요. 부분적으로 다운로드된 파일이 여전히 존재한다면, 네이티브 클라이언트(native client)는 누락된 범위(range)만 요청합니다.
const modelPath = `${documentDirectoryPath}/model.gguf`
await downloadFile({
...
왜 그냥 fetch를 사용하지 않나요?
작은 파일의 경우, 일반적인 앱 수준의 다운로드 로직으로도 충분합니다.
Orb의 경우, 파일이 작지 않습니다. 로컬 AI 모델 다운로드는 지루한 실제 모바일 환경의 동작들, 즉 불안정한 Wi-Fi, 앱의 백그라운드 전환, 재시도, Android에서의 포그라운드 서비스(foreground service) 기대 동작, 그리고 사용자가 나중에 앱을 다시 여는 상황 등을 견뎌내야 합니다.
저는 대용량 전송이 네이티브(native) 상태로 유지되기를 원했습니다:
- 파일 바이트가 JS 브릿지(JS bridge)를 통과하지 않음
- 각 플랫폼에서의 네이티브 네트워킹(native networking) 동작
- UI를 위한 진행 상황 이벤트(progress events)
- 서버가 범위(Range)를 지원할 때 부분 파일 복구 가능
- 재개 메타데이터(resume metadata)가 잘못되었거나 지원되지 않을 때의 안전한 재시작
이 패키지는 아직 완전한 다운로드 매니저(download manager)가 되려고 시도하는 단계는 아닙니다. 현재는 태스크 ID(task IDs), 취소(cancellation), 지속성 큐(persistent queue), 체크섬(checksums), 업로드(uploads), 또는 일반적인 요청/응답 클라이언트(request/response client)를 노출하지 않습니다. 현재의 목표는 더 좁습니다. 즉, 대용량 직접 파일 다운로드(direct-to-file downloads)를 실제 제품 흐름을 구축할 수 있을 만큼 충분히 신뢰할 수 있게 만드는 것입니다.
설치
npm install react-native-client react-native-nitro-modules
yarn add react-native-client react-native-nitro-modules
bun add react-native-client react-native-nitro-modules
iOS의 경우:
cd ios
pod install
Android는 일반적인 React Native 오토링크(autolinking)를 통해 작동해야 합니다.
현재 상태
이 패키지는 초기 단계이지만, 설계된 다운로드 흐름을 위해 사용하기에는 적합합니다.
현재 버전: 0.0.3
요구 사항:
- React Native 앱
react-native-nitro-modules >=0.35.0 <0.36.0- Android 및/또는 iOS 네이티브 빌드
README에는 Android의 재개 (resume) 동작을 보여주는 데모가 포함되어 있습니다: 네이티브 백그라운드 다운로드를 시작하고, 앱을 홈 화면으로 보낸 뒤, 전송 화면으로 돌아오고, 앱을 강제 종료한 다음, 다시 실행하여 부분 파일로부터 재개하는 과정을 보여줍니다.
이 프로젝트를 공개하는 이유
Orb에는 이것이 필요했습니다. 왜냐하면 프라이빗 오프라인 AI (private offline AI)에는 놀라울 정도로 매력적이지 않은 병목 현상이 있기 때문입니다. 바로 모델을 기기에 깔끔하게 설치하는 과정입니다. 사람들의 관심은 AI 부분에 집중되지만, 첫 사용자 경험 (user experience)은 종종 단순히 실패해서는 안 되는 대용량 다운로드 과정인 경우가 많습니다.
만약 대용량 파일을 다운로드하는 React Native 앱을 구축하고 계신다면, API가 너무 커지기 전에 피드백을 주시면 감사하겠습니다.
다음으로 유용할 기능들은 아마도 다음과 같습니다:
- 작업 ID (task IDs) 및 취소 (cancellation)
- 지속적인 백그라운드 작업 레지스트리 (persistent background task registry)
- 요청 헤더 (request headers) 및 응답 메타데이터 (response metadata)
- 체크섬 검증 (checksum verification)
- 업로드 지원 (upload support)
- 파일 다운로드를 넘어선 더 넓은 범위의 HTTP API
GitHub: https://github.com/zraisan/react-native-client
NPM: https://www.npmjs.com/package/react-native-client
Google Play의 Orb: https://play.google.com/store/apps/details?id=com.falaq.orb
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기