downloadAndSave method

Future<Uint8List> downloadAndSave(
  1. String source, {
  2. Map<String, dynamic>? headers,
  3. ProgressCallback? onReceiveProgress,
})

Downloads data from the given source and saves it to the cache.

If the data is already cached, it returns the cached bytes directly. Otherwise, it determines the source type (network, asset, local file, data URI, base64) fetches the data, saves it to the cache using the source string as the key, and returns the downloaded bytes.

  • source: The URL, file path, asset path, data URI, or base64 string.
  • headers: Optional HTTP headers for network requests.
  • onReceiveProgress: Optional callback for tracking download progress.

Throws an exception if the source is invalid or download fails.

Implementation

Future<Uint8List> downloadAndSave(
  String source, {
  Map<String, dynamic>? headers,
  ProgressCallback? onReceiveProgress,
}) async {
  try {
    final cached = await _cache.get(source);
    return cached;
    // ignore: empty_catches
  } catch (e) {}

  final uri = Uri.tryParse(source);

  if (source.startsWith('assets/')) {
    final byteData = await rootBundle.load(source);
    final bytes = Uint8List.view(byteData.buffer);
    await _cache.set(source, bytes);
    return bytes;
  } else if (uri != null && uri.scheme == 'data') {
    final data = uri.data;
    if (data == null) {
      throw Exception('Invalid data URI');
    }
    final bytes = data.contentAsBytes();
    await _cache.set(source, bytes);
    return bytes;
  } else if (uri != null &&
      (uri.scheme == 'http' ||
          uri.scheme == 'https' ||
          uri.scheme == 'blob')) {
    final response = await _dio.get(
      source,
      options: Options(headers: headers, responseType: ResponseType.bytes),
      onReceiveProgress: onReceiveProgress,
    );

    if (response.statusCode != 200) {
      throw DioException.badResponse(
        statusCode: response.statusCode ?? -1,
        requestOptions: response.requestOptions,
        response: response,
      );
    }

    final bytes = response.data as Uint8List;
    await _cache.set(source, bytes);

    return bytes;
  } else {
    try {
      final xfile = XFile(source);
      final bytes = await xfile.readAsBytes();
      await _cache.set(source, bytes);
      return bytes;
      // ignore: empty_catches
    } catch (e) {}

    try {
      final bytes = base64Decode(source);
      await _cache.set(source, bytes);
      return bytes;
      // ignore: empty_catches
    } catch (e) {}

    throw Exception('Invalid source: cannot be processed');
  }
}