File Download and Directory Management in Hybrid Mobile Applications
Managing local file storage in hybrid applications requires handling both directory structures and remote assets. The HTML5 Plus API provides filesystem access through the plus.io namespace combined with the downloader module.
To ensure a directory exists before writing files:
const ensureDirectoryExists = (dirPath, onSuccess, onError) => {
const fullPath = `_downloads/${dirPath}`;
plus.io.resolveLocalFileSystemURL(fullPath, (existingEntry) => {
const physicalPath = plus.io.convertLocalFileSystemURL(fullPath);
console.log(`Directory verified: ${physicalPath}`);
if (onSuccess) onSuccess(existingEntry, physicalPath);
}, (error) => {
console.log(`Creating directory: ${fullPath}`);
plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, (fs) => {
fs.root.getDirectory(
fullPath,
{ create: true, exclusive: false },
(newEntry) => {
console.log('Directory created successfully');
if (onSuccess) onSuccess(newEntry, fullPath);
},
(createError) => {
console.error('Directory creation failed', createError);
if (onError) onError(createError);
}
);
});
});
};
For retrieving remote resources and persisting them locally:
const fetchRemoteAsset = (sourceUrl, destinationPath) => {
const localFile = plus.io.convertLocalFileSystemURL(destinationPath);
const downloadTask = plus.downloader.createDownload(
sourceUrl,
{
method: 'GET',
filename: localFile,
timeout: 30,
retry: 1
},
(completedTask, statusCode) => {
if (statusCode === 200) {
console.log(`Asset saved to: ${destinationPath}`);
} else {
console.error(`Download failed with status: ${statusCode}`);
completedTask.abort();
}
}
);
downloadTask.start();
};
Creating standalone empty directories and placeholder files:
const initializeStorageStructure = (baseName, fileName) => {
const storagePath = `_downloads/${baseName}`;
const absoluteLocation = plus.io.convertLocalFileSystemURL(storagePath);
console.log(`Initializing storage at: ${absoluteLocation}`);
plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, (filesystem) => {
filesystem.root.getDirectory(
storagePath,
{ create: true },
(dirEntry) => {
console.log('Storage directory ready');
const markerFile = `${storagePath}/${fileName || 'placeholder.txt'}`;
filesystem.root.getFile(
markerFile,
{ create: true, exclusive: false },
(fileEntry) => {
console.log('Marker file established');
},
(fileError) => {
console.warn('Marker creation error', fileError);
}
);
},
(dirError) => {
console.error('Storage initialization failed', dirError);
}
);
});
};
Usage workflow combines these operations by first verifying the directory structure, then initiating transfers:
const targetFolder = 'archives/documents';
const remoteSource = 'https://example.com/document.pdf';
const localTarget = `_downloads/archives/documents/report.pdf`;
ensureDirectoryExists(targetFolder, () => {
fetchRemoteAsset(remoteSource, localTarget);
});
This aprpoach handles the conversion between sandbox-relative paths (such as _downloads/) and platform-specific absolute paths automatically, ensuring compatibility across different mobile operating systems while maintaining clean separation between network operatoins and filesystem management.