downloadAndCacheFile method

Future<void> downloadAndCacheFile({
  1. bool runInBackground = true,
})

Downloads and caches a file in the local filesystem.

This method creates an isolate to handle file downloading in the background, preventing UI jank. It stores the file in a directory and handles HTTP errors and exceptions gracefully by printing error messages.

No return value. This function operates asynchronously.

Implementation

Future<void> downloadAndCacheFile({
  bool runInBackground = true
}) async {
  final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  final String documentsDirectory = appDocumentsDirectory.path;
  final directory = Directory('$documentsDirectory/cached_images');

  if (!directory.existsSync()) {
    directory.createSync(recursive: true);
  }

  final filePath = '${directory.path}/$id';
  final fileExists = await File(filePath).exists();

  if (fileExists) {
    await _retrieveAndSetCachedFile();
    print('File is already cached: $filePath');
    return;
  }

  final ReceivePort receivePort = ReceivePort();
  final Completer<void> completer = Completer<void>();

  if(!runInBackground) {
    await Isolate.spawn(
      _downloadFile,
      {
        'id': id,
        'downloadUrl': path,
        'documentsDirectory': documentsDirectory,
        'completerSendPort': receivePort.sendPort,
      },
      onExit: receivePort.sendPort,
    );

    // Listen for completion signal from the spawned isolate
    receivePort.listen((_) {
      completer.complete();
      receivePort.close(); // Close the receive port after completion
    });

    // Wait for the isolate to complete before returning
    await completer.future;
    await _retrieveAndSetCachedFile();
    return;
  }

  Isolate.spawn(
    _downloadFile,
    {
      'id': id,
      'downloadUrl': path,
      'documentsDirectory': documentsDirectory,
      'completerSendPort': receivePort.sendPort,
    },
    onExit: receivePort.sendPort,
  ).then((value) => null);

  // Listen for completion signal from the spawned isolate
  receivePort.listen((_) {
    _retrieveAndSetCachedFile().then((value) => null);
    receivePort.close(); // Close the receive port after completion
  });
}