Complete API reference for the Vision SDK Model Management system.
- Overview
- Initialization
- Download Operations
- Load/Unload Operations
- Query Operations
- Delete Operations
- Prediction
- Event Listeners
- Types & Interfaces
- Error Handling
- Platform Differences
- Migration Guide
The Model Management API provides fine-grained control over the lifecycle of on-device ML models. This includes downloading, loading into memory, querying status, making predictions, and cleanup operations.
- Download: Fetch model files from server to disk
- Load: Load model from disk into memory for inference
- Unload: Remove model from memory (files remain on disk)
- Delete: Permanently remove model files from disk
- OCRModule: Type representing a specific model (type + size combination)
import { VisionCore } from 'react-native-vision-sdk';
// 1. Initialize (REQUIRED on Android, optional on iOS)
VisionCore.initializeModelManager({ maxConcurrentDownloads: 2 });
// 2. Download model
await VisionCore.downloadModel(
{ type: 'shipping_label', size: 'large' },
apiKey,
token
);
// 3. Load into memory
await VisionCore.loadOCRModel(
{ type: 'shipping_label', size: 'large' },
apiKey,
token
);
// 4. Make predictions
const result = await VisionCore.predictWithModule(
{ type: 'shipping_label', size: 'large' },
imageUri,
barcodes
);
// 5. Cleanup
await VisionCore.unloadModel({ type: 'shipping_label', size: 'large' });
await VisionCore.deleteModel({ type: 'shipping_label', size: 'large' });Initialize the Model Manager singleton with configuration options.
Signature:
initializeModelManager(config: ModelManagerConfig): voidParameters:
config(ModelManagerConfig):maxConcurrentDownloads?: number- Maximum concurrent downloads (default: 1)enableLogging?: boolean- Enable debug logging (default: false)
Example:
VisionCore.initializeModelManager({
maxConcurrentDownloads: 3,
enableLogging: true
});Platform Requirements:
- Android: REQUIRED - Must be called before any model operations
- iOS: Not needed - This method exists only for API consistency. iOS has a hardcoded implementation that does nothing. You can safely skip calling this on iOS.
Notes:
- Android: Should be called once, typically at app startup
- Android: Calling multiple times will reinitialize with new config
- Android: Model operations will fail without initialization
- iOS: This method is a no-op (does nothing)
Check if the Model Manager has been initialized.
Signature:
isModelManagerInitialized(): booleanReturns:
boolean-trueif initialized,falseotherwise
Example:
// Android: Check before any operations
if (!VisionCore.isModelManagerInitialized()) {
VisionCore.initializeModelManager({ maxConcurrentDownloads: 2 });
}
// Now safe to proceed with downloads/loads
await VisionCore.downloadModel(module, apiKey, token);Platform Notes:
- Android: Returns
falseuntilinitializeModelManager()is called - iOS: Always returns
true- This is a hardcoded implementation for API consistency. iOS doesn't require initialization, so this method always returnstrueregardless of whetherinitializeModelManager()was called.
Download a model from the server to device storage.
Signature:
downloadModel(
module: OCRModule,
apiKey?: string | null,
token?: string | null,
progressCallback?: (progress: DownloadProgress) => void
): Promise<void>Parameters:
module(OCRModule): Model to downloadtype: 'shipping_label' | 'item_label' | 'bill_of_lading' | 'document_classification'size: 'nano' | 'micro' | 'small' | 'medium' | 'large' | 'xlarge'
apiKey(string | null, optional): API key for authenticationtoken(string | null, optional): Auth token for authenticationprogressCallback(function, optional): Progress updates
Returns:
Promise<void>- Resolves when download completes
Example:
await VisionCore.downloadModel(
{ type: 'shipping_label', size: 'large' },
apiKey,
token,
(progress) => {
console.log(`Download progress: ${(progress.progress * 100).toFixed(1)}%`);
}
);Progress Callback:
The callback receives a DownloadProgress object:
{
module: OCRModule; // The module being downloaded
progress: number; // 0.0 to 1.0 (download progress percentage)
}Error Handling:
try {
await VisionCore.downloadModel(module, apiKey, token, (progress) => {
console.log(`Progress: ${(progress.progress * 100).toFixed(1)}%`);
});
console.log('Download complete');
} catch (error) {
console.error('Download failed:', error.message);
}Cancel an active download operation for a specific model.
Signature:
cancelDownload(module: OCRModule): Promise<boolean>Parameters:
module(OCRModule): The model whose download you want to cancel
Returns:
Promise<boolean>-trueif cancelled,falseif no active download for this model
Example:
const module = { type: 'shipping_label', size: 'large' };
// Start download
VisionCore.downloadModel(module, apiKey, token, (progress) => {
console.log(`Progress: ${progress.progress * 100}%`);
});
// Later... cancel the download for this specific model
const cancelled = await VisionCore.cancelDownload(module);
if (cancelled) {
console.log('Download cancelled successfully');
}Note: Cancels the download for the specified model. If multiple downloads are in progress, only the download for this specific model will be cancelled.
Load a model from disk into memory for inference.
Signature:
loadOCRModel(
module: OCRModule,
apiKey?: string | null,
token?: string | null,
executionProvider?: ExecutionProvider
): Promise<void>Parameters:
module(OCRModule): Model to loadapiKey(string | null, optional): API keytoken(string | null, optional): Auth tokenexecutionProvider(ExecutionProvider, optional): Android only'CPU'(default) - Best compatibility'NNAPI'- Android Neural Networks API'XNNPACK'- Optimized for ARM
Returns:
Promise<void>- Resolves when loaded
Example:
// Basic usage (CPU execution)
await VisionCore.loadOCRModel(
{ type: 'shipping_label', size: 'large' },
apiKey,
token
);
// Android: Use NNAPI for potentially faster inference
await VisionCore.loadOCRModel(
{ type: 'shipping_label', size: 'large' },
apiKey,
token,
'NNAPI'
);Notes:
- If model not downloaded, will automatically download first
- Loading the same model again has no effect
- iOS ignores
executionProviderparameter
Unload a model from memory. Files remain on disk for faster reloading.
Signature:
unloadModel(module: OCRModule): Promise<boolean>Parameters:
module(OCRModule): Model to unload
Returns:
Promise<boolean>-trueif unloaded,falseif wasn't loaded
Example:
const unloaded = await VisionCore.unloadModel({
type: 'shipping_label',
size: 'large'
});
if (unloaded) {
console.log('Model unloaded from memory');
} else {
console.log('Model was not loaded');
}Platform Note:
- iOS: Granular unloading of specific models
- Android: Due to singleton pattern, unloads ALL models
Check if a specific model is currently loaded in memory.
Signature:
isModelLoaded(module: OCRModule): booleanParameters:
module(OCRModule): Model to check
Returns:
boolean-trueif loaded,falseotherwise
Example:
const loaded = VisionCore.isModelLoaded({
type: 'shipping_label',
size: 'large'
});
if (!loaded) {
await VisionCore.loadOCRModel(module, apiKey, token);
}Get the number of models currently loaded in memory.
Signature:
getLoadedModelCount(): numberReturns:
number- Count of loaded models
Example:
const count = VisionCore.getLoadedModelCount();
console.log(`${count} model(s) currently loaded`);
if (count > 2) {
// Unload some models to free memory
}List all models downloaded to device storage.
Signature:
findDownloadedModels(): Promise<ModelInfo[]>Returns:
Promise<ModelInfo[]>- Array of downloaded models
Example:
const downloaded = await VisionCore.findDownloadedModels();
downloaded.forEach(model => {
console.log(`Model: ${model.module.type} (${model.module.size})`);
console.log(` Size: ${(model.sizeInBytes / 1024 / 1024).toFixed(2)} MB`);
console.log(` Path: ${model.filePath}`);
console.log(` Downloaded: ${model.downloadedAt}`);
});ModelInfo Structure:
{
module: OCRModule;
sizeInBytes: number;
filePath: string;
downloadedAt: string; // ISO 8601 timestamp
isLoaded: boolean;
}Find information about a specific downloaded model.
Signature:
findDownloadedModel(module: OCRModule): Promise<ModelInfo | null>Parameters:
module(OCRModule): Model to find
Returns:
Promise<ModelInfo | null>- Model info if found,nullotherwise
Example:
const modelInfo = await VisionCore.findDownloadedModel({
type: 'shipping_label',
size: 'large'
});
if (modelInfo) {
console.log('Model found:', modelInfo.filePath);
} else {
console.log('Model not downloaded');
// Download it
await VisionCore.downloadModel(module, apiKey, token);
}List all models currently loaded in memory.
Signature:
findLoadedModels(): Promise<ModelInfo[]>Returns:
Promise<ModelInfo[]>- Array of loaded models
Example:
const loaded = await VisionCore.findLoadedModels();
console.log(`${loaded.length} model(s) loaded:`);
loaded.forEach(model => {
console.log(`- ${model.module.type} (${model.module.size})`);
});Permanently delete a model from disk.
Signature:
deleteModel(module: OCRModule): Promise<boolean>Parameters:
module(OCRModule): Model to delete
Returns:
Promise<boolean>-trueif deleted,falseif not found
Example:
const deleted = await VisionCore.deleteModel({
type: 'shipping_label',
size: 'large'
});
if (deleted) {
console.log('Model deleted from disk');
} else {
console.log('Model was not found on disk');
}Notes:
- Model will be unloaded from memory if currently loaded
- Deletion is permanent - model must be re-downloaded to use again
- Frees up disk space
Complete Cleanup Pattern:
// Unload from memory first (optional - delete will do this)
await VisionCore.unloadModel(module);
// Delete from disk
await VisionCore.deleteModel(module);Perform OCR prediction using a specific model.
Signature:
predictWithModule(
module: OCRModule,
imagePath: string,
barcodes: string[]
): Promise<any>Parameters:
module(OCRModule): The model to use for predictionimagePath(string): Path to image file or URIbarcodes(string[]): Array of barcode strings detected in image
Returns:
Promise<any>- Prediction result (structure varies by model type)
Example:
const result = await VisionCore.predictWithModule(
{ type: 'shipping_label', size: 'large' },
'file:///path/to/image.jpg',
['1234567890', '9876543210']
);
console.log('Prediction:', result);Model Types & Results:
Shipping Label:
{
sender: {
name?: string;
address?: string;
// ...
};
recipient: {
name?: string;
address?: string;
// ...
};
trackingNumber?: string;
// ...
}Item Label:
{
productName?: string;
sku?: string;
barcode?: string;
// ...
}Requires:
- Model must be loaded into memory first
- Image must be accessible from the provided path
Represents a specific model configuration.
type OCRModule = {
type: 'shipping_label' | 'item_label' | 'bill_of_lading' | 'document_classification';
size: 'nano' | 'micro' | 'small' | 'medium' | 'large' | 'xlarge';
};Example:
const module: OCRModule = {
type: 'shipping_label',
size: 'large'
};Configuration for initializing the Model Manager.
type ModelManagerConfig = {
maxConcurrentDownloads?: number;
enableLogging?: boolean;
};Progress information for model downloads.
interface DownloadProgress {
module: OCRModule; // The module being downloaded
progress: number; // 0.0 to 1.0 (download percentage)
}Information about a model on disk.
type ModelInfo = {
module: OCRModule;
sizeInBytes: number;
filePath: string;
downloadedAt: string; // ISO 8601 timestamp
isLoaded: boolean;
};Android-only: ML execution provider.
type ExecutionProvider = 'CPU' | 'NNAPI' | 'XNNPACK';Recommendations:
CPU: Best compatibility, works on all devicesNNAPI: Potentially faster on supported devices (Android 8.1+)XNNPACK: Optimized for ARM processors
try {
await VisionCore.downloadModel(module, apiKey, token);
} catch (error) {
switch (error.code) {
case 'MODEL_NOT_FOUND':
// Invalid model type or size
break;
case 'NETWORK_ERROR':
// No internet connection
break;
case 'AUTHENTICATION_FAILED':
// Invalid API key or token
break;
case 'STORAGE_FULL':
// Insufficient disk space
break;
case 'MODEL_ALREADY_DOWNLOADING':
// Download in progress for this model
break;
default:
console.error('Unexpected error:', error.message);
}
}- Always handle errors:
try {
await VisionCore.loadOCRModel(module, apiKey, token);
} catch (error) {
Alert.alert('Error', `Failed to load model: ${error.message}`);
}- Check status before operations:
// Check if downloaded before loading
const modelInfo = await VisionCore.findDownloadedModel(module);
if (!modelInfo) {
await VisionCore.downloadModel(module, apiKey, token);
}
// Check if loaded before prediction
if (!VisionCore.isModelLoaded(module)) {
await VisionCore.loadOCRModel(module, apiKey, token);
}- Handle progress failures:
await VisionCore.downloadModel(module, apiKey, token, (progress) => {
if (progress.status === 'failed') {
Alert.alert('Download Failed', progress.error);
}
});| Feature | iOS | Android |
|---|---|---|
| Initialization | Not needed (hardcoded no-op) | Required (must call before operations) |
| isModelManagerInitialized() | Always returns true |
Returns actual status |
| Model unloading | Granular (specific model) | Granular (specific model) |
| Execution provider | Not exposed | CPU, NNAPI, XNNPACK |
| Concurrent downloads | Supported | Supported |
| Model switching | Supported | Supported |
| Lifecycle events | Full support | Full support |
Initialization Requirement: Android requires explicit initialization of the Model Manager before any model operations. Attempting to download, load, or query models without initialization will result in an error.
// Android: This will fail if not initialized
await VisionCore.downloadModel(module, apiKey, token); // Error
// Android: Correct approach
VisionCore.initializeModelManager({ maxConcurrentDownloads: 2 });
await VisionCore.downloadModel(module, apiKey, token); // Works
// iOS: Works without initialization (initialization methods are no-ops)
await VisionCore.downloadModel(module, apiKey, token); // WorksInitialization Not Required:
iOS does not require initialization. The initializeModelManager() and isModelManagerInitialized() methods were added only for API consistency with Android:
initializeModelManager()- Does nothing (hardcoded no-op)isModelManagerInitialized()- Always returnstrue(hardcoded)
You can safely call these methods for cross-platform code consistency, but they have no effect on iOS.
Model Unloading: Both iOS and Android support granular model unloading. You can unload specific models without affecting other loaded models.
// Both iOS and Android: Unloads only the specified model
await VisionCore.unloadModel({ type: 'shipping_label', size: 'large' });
// Other loaded models remain in memory
const stillLoaded = VisionCore.isModelLoaded({ type: 'item_label', size: 'medium' });
// Returns true if item_label was loadedconst models = [
{ type: 'shipping_label', size: 'large' },
{ type: 'item_label', size: 'medium' },
{ type: 'bill_of_lading', size: 'large' }
];
// Initialize with concurrent downloads
VisionCore.initializeModelManager({ maxConcurrentDownloads: 3 });
// Download all models in parallel
const downloads = models.map(module =>
VisionCore.downloadModel(module, apiKey, token, (progress) => {
console.log(`${progress.module.type}: ${(progress.progress * 100).toFixed(1)}%`);
})
);
// Wait for all downloads
await Promise.all(downloads);
console.log('All downloads complete');const model1 = { type: 'shipping_label', size: 'large' };
const model2 = { type: 'item_label', size: 'medium' };
// Ensure both are downloaded
await VisionCore.downloadModel(model1, apiKey, token);
await VisionCore.downloadModel(model2, apiKey, token);
// Use first model
await VisionCore.loadOCRModel(model1, apiKey, token);
const result1 = await VisionCore.predictWithModule(model1, image1, barcodes1);
// Switch to second model
await VisionCore.unloadModel(model1); // Free memory
await VisionCore.loadOCRModel(model2, apiKey, token);
const result2 = await VisionCore.predictWithModule(model2, image2, barcodes2);const module = { type: 'shipping_label', size: 'large' };
// Check if downloaded
const info = await VisionCore.findDownloadedModel(module);
if (!info) {
console.log('Model not downloaded, downloading now...');
await VisionCore.downloadModel(module, apiKey, token);
}
// Check if loaded
if (!VisionCore.isModelLoaded(module)) {
console.log('Model not loaded, loading now...');
await VisionCore.loadOCRModel(module, apiKey, token);
}
// Now safe to predict
const result = await VisionCore.predictWithModule(module, imagePath, barcodes);- MODEL_MANAGEMENT_IMPLEMENTATION.md - Implementation status and technical details
- README.md - Main SDK documentation
- Example App - Complete working example
Last Updated: 2025-12-15 Version: 2.1.0