downloadToFile method
Download a file directly to disk with progress callback.
Streams data directly to the destination file to avoid holding the entire file in memory. This is critical for large map files (100MB+) to prevent iOS memory exhaustion (EXC_RESOURCE).
destination is the file to write to (will be created/overwritten).
onProgress is called with (bytesReceived, totalBytes).
Returns the total number of bytes written.
Implementation
Future<int> downloadToFile(
String url,
File destination, {
void Function(int received, int total)? onProgress,
}) async {
final request = http.Request('GET', Uri.parse(url));
final response = await _client.send(request);
if (response.statusCode != 200) {
throw Exception('Download failed: HTTP ${response.statusCode}');
}
final contentLength = response.contentLength ?? 0;
int received = 0;
// Ensure parent directory exists
await destination.parent.create(recursive: true);
// Stream directly to file - never hold entire file in memory
final sink = destination.openWrite();
try {
await for (final chunk in response.stream) {
sink.add(chunk);
received += chunk.length;
onProgress?.call(received, contentLength);
}
} finally {
await sink.close();
}
return received;
}