@punk_rock_malchik/react-native-sdk
v1.0.1
Published
React Native SDK for OTA Update System - Over-the-air updates for React Native applications
Downloads
16
Maintainers
Readme
@punk_rock_malchik/react-native-sdk
React Native SDK для системы OTA обновлений. Позволяет обновлять JavaScript bundle и ресурсы React Native приложения без перепубликации через App Store/Google Play.
Установка
npm install @punk_rock_malchik/react-native-sdk @react-native-async-storage/async-storageДополнительные зависимости
Для работы с файловой системой (выберите один вариант)
Вариант 1: react-native-fs (рекомендуется для bare React Native)
npm install react-native-fs
# Для iOS
cd ios && pod installВариант 2: expo-file-system (только для Expo проектов)
npm install expo-file-systemДля вычисления SHA256 checksum (выберите один вариант)
Вариант 1: react-native-crypto (рекомендуется)
npm install react-native-crypto
# Для iOS
cd ios && pod installВариант 2: crypto-js (легковесная альтернатива)
npm install crypto-js
npm install --save-dev @types/crypto-jsВариант 3: expo-crypto (только для Expo проектов)
npm install expo-cryptoБыстрый старт
Базовое использование
import { OTAUpdate } from "@punk_rock_malchik/react-native-sdk";
import { Platform } from "react-native";
import Constants from "expo-constants";
// Инициализация SDK
const ota = new OTAUpdate(
{
apiBaseUrl: "http://localhost:3000/api",
currentVersion: "1.0.0", // Текущая версия bundle
appVersion: Constants.expoConfig?.version || "1.0.0", // Версия нативного приложения
platform: Platform.OS === "ios" ? "ios" : "android",
environment: __DEV__ ? "dev" : "production",
deviceId: "unique-device-id", // Опционально, для rollout логики
},
{
onCheckComplete: (response) => {
if (response.available) {
console.log("Доступно обновление:", response.update?.version);
}
},
onDownloadProgress: (progress) => {
console.log(`Загрузка: ${Math.round(progress.progress * 100)}%`);
},
onInstallComplete: (version) => {
console.log("Обновление установлено:", version);
// Перезагрузить приложение для применения обновления
},
onError: (error) => {
console.error("Ошибка OTA:", error);
},
}
);
// Проверка и установка обновлений
await ota.checkAndInstall();Пример интеграции в React компонент
import React, { useEffect, useState } from "react";
import { View, Text, Button, ActivityIndicator } from "react-native";
import { OTAUpdate } from "@punk_rock_malchik/react-native-sdk";
const App: React.FC = () => {
const [updateStatus, setUpdateStatus] = useState<
"checking" | "downloading" | "installing" | "idle"
>("idle");
const [progress, setProgress] = useState(0);
const [updateInfo, setUpdateInfo] = useState(null);
useEffect(() => {
checkForUpdates();
}, []);
const checkForUpdates = async () => {
try {
setUpdateStatus("checking");
const ota = new OTAUpdate(
{
apiBaseUrl: "http://your-api-url/api",
currentVersion: "1.0.0",
appVersion: "1.0.0",
platform: "ios",
environment: "production",
},
{
onDownloadProgress: (p) => {
setProgress(p.progress);
setUpdateStatus("downloading");
},
onInstallStart: () => {
setUpdateStatus("installing");
},
onInstallComplete: (version) => {
setUpdateStatus("idle");
alert(
`Обновление ${version} установлено! Перезапустите приложение.`
);
},
}
);
await ota.checkAndInstall();
} catch (error) {
console.error("Ошибка обновления:", error);
setUpdateStatus("idle");
}
};
return (
<View>
{updateStatus === "checking" && <ActivityIndicator />}
{updateStatus === "downloading" && (
<View>
<Text>
Загрузка обновления: {Math.round(progress * 100)}%
</Text>
<ActivityIndicator />
</View>
)}
{updateStatus === "installing" && (
<Text>Установка обновления...</Text>
)}
<Button title="Проверить обновления" onPress={checkForUpdates} />
</View>
);
};
export default App;API
Класс OTAUpdate
Главный класс для управления обновлениями.
Конструктор
new OTAUpdate(config: OTAConfig, callbacks?: OTACallbacks)Методы
checkAndInstall(): Promise<CheckUpdateResponse>
Полный цикл: проверка → скачивание → установка.
const response = await ota.checkAndInstall();
if (response.available) {
console.log("Обновление установлено");
}checkOnly(): Promise<CheckUpdateResponse>
Только проверка обновлений без скачивания.
const response = await ota.checkOnly();
if (response.available) {
console.log("Доступно обновление:", response.update?.version);
}downloadAndInstall(update: UpdateInfo): Promise<void>
Скачивание и установка конкретного обновления.
getCurrentVersion(): Promise<string | null>
Получает текущую установленную версию.
rollback(): Promise<string | null>
Откатывает к предыдущей версии.
Конфигурация (OTAConfig)
interface OTAConfig {
apiBaseUrl: string; // URL API (например: http://localhost:3000/api)
currentVersion: string; // Текущая версия bundle
appVersion: string; // Версия нативного приложения
platform: "ios" | "android"; // Платформа
environment: "dev" | "staging" | "production"; // Окружение
deployment?: string; // Deployment name (опционально)
deviceId?: string; // Device ID для rollout (опционально)
timeout?: number; // Таймаут запросов (мс, по умолчанию 10000)
maxRetries?: number; // Максимум попыток скачивания (по умолчанию 3)
}Callbacks (OTACallbacks)
interface OTACallbacks {
onCheckStart?: () => void;
onCheckComplete?: (response: CheckUpdateResponse) => void;
onCheckError?: (error: Error) => void;
onDownloadStart?: () => void;
onDownloadProgress?: (progress: DownloadProgress) => void;
onDownloadComplete?: (filePath: string) => void;
onDownloadError?: (error: Error) => void;
onInstallStart?: () => void;
onInstallComplete?: (version: string) => void;
onInstallError?: (error: Error) => void;
}Структура SDK
react-native-sdk/
├── src/
│ ├── classes/
│ │ ├── OTAUpdate.ts # Главный класс
│ │ ├── UpdateChecker.ts # Проверка обновлений
│ │ ├── BundleDownloader.ts # Скачивание bundle
│ │ ├── BundleInstaller.ts # Установка bundle
│ │ └── StatisticsReporter.ts # Статистика
│ ├── types/
│ │ └── index.ts # TypeScript типы
│ ├── utils/
│ │ ├── http.util.ts # HTTP утилиты
│ │ └── checksum.util.ts # Проверка checksum
│ └── index.ts # Главный экспорт
├── package.json
└── tsconfig.jsonОсобенности
- ✅ Проверка обновлений с кэшированием
- ✅ Скачивание bundle файлов с прогрессом
- ✅ Проверка checksum (SHA256)
- ✅ Автоматическая установка обновлений
- ✅ Откат к предыдущей версии при ошибках
- ✅ Отправка статистики на сервер
- ✅ Retry логика для скачивания
- ✅ TypeScript поддержка
- ✅ Event listeners для отслеживания процесса
Примеры использования
Только проверка обновлений
const ota = new OTAUpdate(config);
const response = await ota.checkOnly();
if (response.available && response.update) {
// Показать диалог пользователю
const shouldUpdate = await showUpdateDialog(response.update);
if (shouldUpdate) {
await ota.downloadAndInstall(response.update);
}
}Кастомная логика скачивания
const checker = new UpdateChecker(config);
const response = await checker.checkForUpdates();
if (response.available && response.update) {
const downloader = new BundleDownloader();
const bundlePath = await downloader.download(
response.update,
(progress) => {
console.log(`${progress.progress * 100}%`);
}
);
// Своя логика установки
// ...
}Откат при ошибке
try {
await ota.checkAndInstall();
} catch (error) {
console.error("Ошибка обновления:", error);
// Автоматический откат уже выполнен
// Но можно и вручную:
const previousVersion = await ota.rollback();
console.log("Откат к версии:", previousVersion);
}Требования
- React Native >= 0.70.0
- TypeScript (рекомендуется)
- Одна из библиотек для файловой системы:
react-native-fs(рекомендуется для bare React Native)expo-file-system(для Expo проектов)
- Одна из библиотек для криптографии:
react-native-crypto(рекомендуется)crypto-js(легковесная альтернатива)expo-crypto(для Expo проектов)
Troubleshooting
Ошибка "No crypto library available"
Установите одну из библиотек для криптографии:
npm install react-native-crypto
# или
npm install crypto-jsОшибка "Neither react-native-fs nor expo-file-system is available"
Установите библиотеку для работы с файловой системой:
npm install react-native-fs
# Для iOS
cd ios && pod installОшибка "AsyncStorage not found"
Установите:
npm install @react-native-async-storage/async-storageBundle не применяется после установки
Убедитесь, что:
- Bundle файл скачан и проверен checksum
- Приложение перезапущено после установки
- Настроена загрузка bundle из правильной директории
Лицензия
MIT
