download method

  1. @override
Future<AdapterResponse> download(
  1. AdapterRequest request,
  2. String savePath, {
  3. ProgressCallback? onProgress,
})
override

Downloads a file from the server.

This method downloads a file and saves it to the specified path on the device. Progress can be tracked using the optional onProgress callback.

Parameters:

  • request: The request configuration for the download
  • savePath: The local file path where the downloaded file will be saved
  • onProgress: Optional callback to track download progress

Returns a Future that completes with an AdapterResponse when the download is complete.

Throws AdapterException if the download fails.

Example:

final request = AdapterRequest(
  baseUrl: 'https://example.com',
  path: '/files/document.pdf',
  method: HttpMethod.get,
);

await adapter.download(
  request,
  '/path/to/save/document.pdf',
  onProgress: (count, total) {
    print('Downloaded: ${(count / total * 100).toStringAsFixed(1)}%');
  },
);

Implementation

@override
Future<AdapterResponse> download(
  AdapterRequest request,
  String savePath, {
  ProgressCallback? onProgress,
}) async {
  // 记录请求历史
  _requestHistory.add(request);

  // 创建 Completer 用于取消
  final completer = Completer<AdapterResponse>();

  // 如果有 cancelToken,注册取消回调
  if (request.cancelToken != null) {
    _registerCancelToken(request.cancelToken!, completer);

    // 如果已经取消,立即抛出异常
    if (request.cancelToken!.isCancelled) {
      throw AdapterException(
        type: AdapterExceptionType.cancel,
        message: request.cancelToken!.cancelReason ?? 'Request cancelled',
      );
    }
  }

  try {
    // 获取模拟配置
    final config = _mockConfigs[request.path];

    // 应用延迟(支持取消)
    if (config?.delay != null) {
      try {
        await Future.any([
          Future.delayed(config!.delay!),
          completer.future,
        ]);

        // 检查是否被取消
        if (completer.isCompleted) {
          throw await completer.future;
        }
      } catch (e) {
        _unregisterCancelToken(request.cancelToken, completer);
        rethrow;
      }
    }

    // 模拟进度回调
    if (onProgress != null) {
      final total = 1024;
      for (var i = 0; i <= 10; i++) {
        await Future.delayed(const Duration(milliseconds: 10));
        onProgress((i * total / 10).toInt(), total);
      }
    }

    // 如果配置了错误,抛出错误
    if (config?.error != null) {
      _unregisterCancelToken(request.cancelToken, completer);
      throw config!.error!;
    }

    // 返回模拟响应
    _unregisterCancelToken(request.cancelToken, completer);
    return config?.response ?? _createDefaultResponse(request, data: savePath);
  } catch (e) {
    _unregisterCancelToken(request.cancelToken, completer);
    rethrow;
  }
}