downloadFile method

  1. @override
Future<String> downloadFile({
  1. required String remotePath,
  2. required String localPath,
})
override

Downloads a file from a remotePath to a localPath on the device.

Implementation

@override
Future<String> downloadFile({
  required String remotePath,
  required String localPath,
}) async {
  final completer = Completer<String>();
  StreamSubscription? progressSubscription;
  try {
    await _icloudSync.download(
      containerId: _containerId,
      relativePath: _sanitizePath(remotePath),
      destinationFilePath: localPath,
      onProgress: (stream) {
        // This listener is now for in-progress updates and potential mid-stream errors.
        progressSubscription = stream.listen(
          (progress) {
            // You can handle progress updates here if needed.
            debugPrint('Download progress: $progress');
          },
          onError: (error) {
            // This handles errors that might occur *during* the download stream.
            if (!completer.isCompleted) {
              // You can still keep your original checks here as a fallback.
              if (error is PlatformException &&
                  error.toString().contains('NSURLErrorDomain Code=-1009')) {
                completer
                    .completeError(NoConnectionException(error.toString()));
              } else if (error
                  .toString()
                  .contains('NSCocoaErrorDomain Code=4')) {
                completer.completeError(NotFoundException(error.toString()));
              } else {
                completer.completeError(Exception(
                    'iCloud download failed during stream: $error'));
              }
            }
          },
          onDone: () {
            if (!completer.isCompleted) {
              completer.complete(localPath);
            }
          },
          cancelOnError: true,
        );
      },
    );
    // If the download call completes without an error but the completer is still not done,
    // it means we are waiting for the onDone callback from the stream.
  } on PlatformException catch (e) {
    // **FIX:** Handle initial errors, like "file not found", here.
    if (!completer.isCompleted) {
      if (e.toString().contains('NSCocoaErrorDomain Code=4')) {
        completer.completeError(
            NotFoundException('File not found at path: $remotePath'));
      } else if (e.toString().contains('NSURLErrorDomain Code=-1009')) {
        completer.completeError(NoConnectionException(
            'Failed to download from iCloud. Check your internet connection.'));
      } else {
        completer.completeError(e); // Rethrow other platform exceptions.
      }
    }
  } catch (e) {
    // Catch any other general exceptions.
    if (!completer.isCompleted) {
      completer.completeError(e);
    }
  }

  try {
    return await completer.future;
  } finally {
    // Ensure the subscription is cancelled to prevent memory leaks.
    await progressSubscription?.cancel();
  }
}