-
Notifications
You must be signed in to change notification settings - Fork 384
[Bug report] iOS: loadFile for images blocks UI, progress handler ineffective #1364
Description
Version
3.8.3
Platforms
iOS
Device Model
Iphone 11 and Iphone 15
flutter info
[✓] Flutter (Channel stable, 3.38.1, on macOS 26.1 25B78 darwin-arm64, locale en-US)
• Flutter version 3.38.1 on channel stable at /Users/<USER>/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision b45fa18946 (2 months ago), 2025-11-12 22:09:06 -0600
• Engine revision b5990e5ccc
• Dart version 3.10.0
• DevTools version 2.51.1
[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
• Android SDK at /Users/<USER>/Library/Android/sdk
• Platform android-36, build-tools 36.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 21.0.6+-13391695-b895.109)
[✓] Xcode - develop for iOS and macOS (Xcode 26.2)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17C52
• CocoaPods version 1.16.2
[✓] Connected device (4 available)
• iPhone (mobile) • <DEVICE_ID_1> • ios • iOS 26.2
• iPhone (mobile) • <DEVICE_ID_2> • ios • iOS 26.2
• macOS (desktop) • macos • darwin-arm64 • macOS 26.1
• Chrome (web) • chrome • web-javascript
[✓] Network resources
• All expected network resources are available.How to reproduce?
Description
When using AssetEntity.loadFile for images on iOS, the plugin appears to be executing heavy I/O or image processing tasks on the Main Thread. This results in a completely frozen UI during the operation.
Crucially, the PMProgressHandler becomes ineffective: the stream events are not delivered while the work is happening. Instead, as soon as the UI unfreezes (when the function is nearly finished), all progress events are delivered in a single "burst." This makes it impossible to show a real-time progress bar or status update to the user.
Key Observations:
iOS Specific: This behavior is observed on iOS.
Image Specific: Loading videos works perfectly with smooth, real-time progress updates.
Cloud & Local: The UI freeze occurs even if the asset is locally available, though it is most noticeable during iCloud downloads.
Main Thread Block: The fact that the stream events arrive all at once after the UI unfreezes suggests the platform channel is being blocked by the synchronous work on the native side.
Steps to Reproduce the issue:
Select an image AssetEntity.
Call loadFile(isOrigin: false) with a PMProgressHandler.
Listen to the progress stream and attempt to update the UI or print the progress.
Observation: The app UI hangs. Nothing prints to the console for several seconds. Once the file is ready, the UI unfreezes and all progress increments (e.g., 0.1, 0.5, 1.0) print at the exact same millisecond.
Logs
Example code (optional)
Future<File?> importAsset(AssetEntity selectedAsset, bool isImage, ValueNotifier loadingTextNotifier) async{
final isLocallyAvailable = await selectedAsset.isLocallyAvailable();
final progressHandler = PMProgressHandler();
final progressSubscription = progressHandler.stream.listen((event) {
final progress = (event.progress * 100).toStringAsFixed(0);
print('value here: ${event.state.name} $progress ');
if ((event.state == PMRequestState.prepare ||
event.state == PMRequestState.loading) &&
!isLocallyAvailable) {
if (isImage) {
loadingTextNotifier.value = 'Downloading Image... $progress%';
} else {
loadingTextNotifier.value = 'Downloading Video... $progress%';
}
} else {
if (isImage) {
loadingTextNotifier.value = 'Importing Image...';
} else {
loadingTextNotifier.value = 'Importing Video...';
}
}
});
final file = await selectedAsset.loadFile(
progressHandler: progressHandler,
isOrigin: !isImage,
);
progressSubscription.cancel();
return file;
}