Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ See [`packages/file_picker/README.md`](packages/file_picker/README.md) for the f

## Migration

- **Upgrading to v14?** See the [Migrating to v14 Guide](packages/file_picker/README.md#migrating-to-v14) for the `cross_file` 0.4.0 migration, the raised minimum versions and the removed web reading options.
- **Upgrading to v13?** See the [Migrating to v13 Guide](packages/file_picker/README.md#migrating-to-v13) for details on `PlatformFile.length()` returning `Future<int?>` and the removal of legacy v12-deprecated parameters.
- **Upgrading from pre-v12?** See the [Migrating to v12 Guide](packages/file_picker/README.md#migrating-to-v12) for the federated architecture changes (`FilePicker.pickFiles()` returning `List<PlatformFile>`, platform options, and streaming).

Expand Down
14 changes: 7 additions & 7 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ publish_to: 'none'
resolution: workspace

environment:
sdk: ">=3.10.0 <4.0.0"
sdk: ">=3.11.0 <4.0.0"

formatter:
page_width: 80

dependencies:
flutter:
sdk: flutter
file_picker: ^13.0.0
android_file_picker: ^2.0.0
file_picker_darwin: ^2.0.0
file_picker_linux: ^2.0.0
file_picker_web: ^4.0.0
windows_file_picker: ^2.0.0
file_picker: ^14.0.0
android_file_picker: ^3.0.0
file_picker_darwin: ^3.0.0
file_picker_linux: ^3.0.0
file_picker_web: ^5.0.0
windows_file_picker: ^3.0.0
file: ^7.0.1

dev_dependencies:
Expand Down
7 changes: 7 additions & 0 deletions packages/file_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 14.0.0

- **BREAKING CHANGE**: Migrated to `cross_file` 0.4.0. `PlatformFile.xFile` now returns the new `XFile` API. See the [migration guide](https://github.com/vicajilau/flutter_file_picker/tree/main/packages/file_picker#migrating-to-v14). [#2224](https://github.com/vicajilau/flutter_file_picker/issues/2224)
- **BREAKING CHANGE**: Requires Flutter 3.41, Dart 3.11, Android SDK 24 and macOS 10.15.
- **BREAKING CHANGE**: Removed `withData`, `withReadStream` and `readSequential` from `FilePickerWebOptions`.
- `getDirectoryPath()` and `saveFile()` now take `darwinOptions`, so `DarwinOptions.acceptLabel` also sets their confirm button text on macOS. [#1861](https://github.com/vicajilau/flutter_file_picker/issues/1861)

## 13.1.0

- Added support for UIScene on iOS.
Expand Down
25 changes: 24 additions & 1 deletion packages/file_picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,30 @@ See the [official API reference on pub.dev](https://pub.dev/documentation/file_p

### Darwin implementation notes

The iOS and macOS native implementations live under the shared Darwin source tree (`file_picker_darwin`). The iOS implementation requires iOS 14.0 or newer because it uses `PHPickerViewController` and `PHPickerResult`.
The iOS and macOS native implementations live under the shared Darwin source tree (`file_picker_darwin`). The iOS implementation requires iOS 14.0 or newer because it uses `PHPickerViewController` and `PHPickerResult`. The macOS implementation requires macOS 10.15 or newer.

## Migrating to v14

1. **Minimum Versions Raised**: Flutter 3.41, Dart 3.11, Android SDK 24 and macOS 10.15, required by `cross_file` 0.4.0.

2. **`PlatformFile.xFile` Uses `cross_file` 0.4.0**:
* `XFile.path`, `XFile.mimeType`, `XFile.saveTo()` and `XFile.fromData` no longer exist, and `XFile.name` is now `Future<String?> name()`.
* Use `PlatformFile.path`, `PlatformFile.name`, `readAsBytes()` and `readAsByteStream()` when you do not need an `XFile`. For a file system path, check for a `FileSystemXFile`:

```dart
import 'package:cross_file/cross_file.dart';

final path = switch (file.xFile) {
FileSystemXFile(:final path) => path,
_ => null,
};
```
* See the [`cross_file` changelog](https://pub.dev/packages/cross_file/changelog) for the full list.

3. **Web Reading Options Removed**:
* `withData`, `withReadStream` and `readSequential` are removed from `FilePickerWebOptions`. Picked files are no longer read at pick time, and `readAsBytes()`/`readAsByteStream()` read them on demand.
* **v13**: `FilePickerWebOptions(withData: false, withReadStream: true, cancelUploadOnWindowBlur: false)`
* **v14**: `FilePickerWebOptions(cancelUploadOnWindowBlur: false)`

## Migrating to v13

Expand Down
8 changes: 6 additions & 2 deletions packages/file_picker/lib/src/file_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,15 @@ abstract final class FilePicker {
/// The [dialogTitle], if provided, will be used as the title for the directory picker dialog.
/// The [initialDirectory], if provided, will be used as the initial directory path for the directory picker.
///
/// The [androidOptions], [windowsOptions], [linuxOptions], and [webOptions] parameters
/// The [androidOptions], [darwinOptions], [windowsOptions], [linuxOptions], and [webOptions] parameters
/// allow for platform-specific configurations when configuring the directory picker.
///
/// Returns a [String] containing the selected directory path, or `null` if canceled.
static Future<String?> getDirectoryPath({
String? dialogTitle,
String? initialDirectory,
AndroidOptions androidOptions = const AndroidOptions(),
DarwinOptions darwinOptions = const DarwinOptions(),
WindowsOptions windowsOptions = const WindowsOptions(),
LinuxOptions linuxOptions = const LinuxOptions(),
WebOptions webOptions = const WebOptions(),
Expand All @@ -145,6 +146,7 @@ abstract final class FilePicker {
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
androidOptions: androidOptions,
darwinOptions: darwinOptions,
windowsOptions: windowsOptions,
linuxOptions: linuxOptions,
webOptions: webOptions,
Expand All @@ -161,7 +163,7 @@ abstract final class FilePicker {
/// The [initialDirectory], if provided, will be used as the initial directory path for the save file dialog.
/// The [onFileSaving] callback, if provided, is triggered when the save dialog changes status.
///
/// The [windowsOptions], [linuxOptions], and [webOptions] parameters
/// The [darwinOptions], [windowsOptions], [linuxOptions], and [webOptions] parameters
/// allow for platform-specific configurations when configuring the save file dialog.
///
/// Returns the [Uri] of the saved file, or `null` if the user canceled the operation.
Expand All @@ -175,6 +177,7 @@ abstract final class FilePicker {
FileType type = FileType.any,
List<String>? allowedExtensions,
Function(FilePickerStatus)? onFileSaving,
DarwinOptions darwinOptions = const DarwinOptions(),
WindowsOptions windowsOptions = const WindowsOptions(),
LinuxOptions linuxOptions = const LinuxOptions(),
WebOptions webOptions = const WebOptions(),
Expand All @@ -186,6 +189,7 @@ abstract final class FilePicker {
dialogTitle: dialogTitle,
initialDirectory: initialDirectory,
onFileSaving: onFileSaving,
darwinOptions: darwinOptions,
windowsOptions: windowsOptions,
linuxOptions: linuxOptions,
webOptions: webOptions,
Expand Down
20 changes: 10 additions & 10 deletions packages/file_picker/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ topics:
- storage
- desktop
- web
version: 13.1.0
version: 14.0.0

resolution: workspace

environment:
sdk: ">=3.10.0 <4.0.0"
flutter: ">=3.38.0"
sdk: ">=3.11.0 <4.0.0"
flutter: ">=3.41.0"

dependencies:
flutter:
sdk: flutter

file_picker_platform_interface: ^4.0.0
android_file_picker: ^2.0.0
file_picker_darwin: ^2.1.0
file_picker_linux: ^2.0.0
windows_file_picker: ^2.0.0
file_picker_web: ^4.0.0
cross_file: ^0.3.5+4
file_picker_platform_interface: ^5.0.0
android_file_picker: ^3.0.0
file_picker_darwin: ^3.0.0
file_picker_linux: ^3.0.0
windows_file_picker: ^3.0.0
file_picker_web: ^5.0.0
cross_file: ^0.4.0

dev_dependencies:
flutter_test:
Expand Down
2 changes: 1 addition & 1 deletion packages/file_picker/test/file_picker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ base class TestPlatformFile extends PlatformFile {
final Uri uri;

@override
XFile get xFile => XFile(path ?? '');
XFile get xFile => XFile.fileSystem(path: path ?? '');

@override
int? lengthSync() => 100;
Expand Down
4 changes: 4 additions & 0 deletions packages/file_picker_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.0.0

- **BREAKING CHANGE**: Migrated to `cross_file` 0.4.0. `PlatformFile.xFile` now returns the new `XFile` API. Requires Flutter 3.41, Dart 3.11 and Android SDK 24. [#2224](https://github.com/vicajilau/flutter_file_picker/issues/2224)

## 2.0.1

- Fixed `pickFileAndDirectoryPaths()` returning percent-encoded paths that do not exist. [#2225](https://github.com/vicajilau/flutter_file_picker/issues/2225)
Expand Down
2 changes: 1 addition & 1 deletion packages/file_picker_android/android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ configure<LibraryExtension> {
namespace = "com.mr.flutter.plugin.filepicker"

defaultConfig {
minSdk = 21
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("proguard-rules.pro")
}
Expand Down
16 changes: 7 additions & 9 deletions packages/file_picker_android/lib/src/android_platform_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ base class AndroidPlatformFile extends PlatformFile {
name: name,
uri: uri,
safHandle: safHandle,
xFile: path.isNotEmpty ? XFile(path, name: name) : null,
bytesLength: data['size'] as int?,
);
}
Expand All @@ -68,15 +67,14 @@ base class AndroidPlatformFile extends PlatformFile {
final XFile? _xFile;
final int? _bytesLength;

/// A [FileSystemXFile] for a picked file cached on disk, or a
/// [ScopedStorageXFile] for a Storage Access Framework `content://` URI.
@override
XFile get xFile {
final file = _xFile;
if (file != null) return file;
if (uri.scheme == 'file') {
return XFile(uri.toFilePath(), name: name);
}
return XFile(uri.toString(), name: name);
}
XFile get xFile =>
_xFile ??
(uri.scheme == 'file'
? XFile.fileSystem(path: uri.toFilePath())
: XFile.scopedStorage(uri: uri.toString()));
Comment thread
vicajilau marked this conversation as resolved.

/// The size Android already reported for this file when it was picked.
@override
Expand Down
2 changes: 2 additions & 0 deletions packages/file_picker_android/lib/src/file_picker_android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class FilePickerAndroid extends FilePickerPlatform {
String? dialogTitle,
String? initialDirectory,
AndroidOptions androidOptions = const FilePickerAndroidOptions(),
DarwinOptions darwinOptions = const DarwinOptions(),
WindowsOptions windowsOptions = const WindowsOptions(),
LinuxOptions linuxOptions = const LinuxOptions(),
WebOptions webOptions = const WebOptions(),
Expand Down Expand Up @@ -195,6 +196,7 @@ class FilePickerAndroid extends FilePickerPlatform {
String? dialogTitle,
String? initialDirectory,
Function(FilePickerStatus)? onFileSaving,
DarwinOptions darwinOptions = const DarwinOptions(),
WindowsOptions windowsOptions = const WindowsOptions(),
LinuxOptions linuxOptions = const LinuxOptions(),
WebOptions webOptions = const WebOptions(),
Expand Down
11 changes: 6 additions & 5 deletions packages/file_picker_android/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: android_file_picker
description: Android implementation of the file_picker plugin, supporting file picking, saving, and Storage Access Framework (SAF) URI grants.
version: 2.0.1
version: 3.0.0
homepage: https://github.com/vicajilau/flutter_file_picker/tree/main/packages/file_picker_android
repository: https://github.com/vicajilau/flutter_file_picker/tree/main/packages/file_picker_android
topics:
Expand All @@ -10,8 +10,8 @@ topics:
resolution: workspace

environment:
sdk: ">=3.10.0 <4.0.0"
flutter: ">=3.38.0"
sdk: ">=3.11.0 <4.0.0"
flutter: ">=3.41.0"

flutter:
plugin:
Expand All @@ -25,11 +25,12 @@ flutter:
dependencies:
flutter:
sdk: flutter
file_picker_platform_interface: ^4.0.0
cross_file: ^0.3.5+4
file_picker_platform_interface: ^5.0.0
cross_file: ^0.4.0
path: ^1.9.0

dev_dependencies:
cross_file_io: ^1.0.0
flutter_test:
sdk: flutter
flutter_lints: ^6.0.0
38 changes: 38 additions & 0 deletions packages/file_picker_android/test/platform_file_read_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'dart:convert';
import 'dart:io';

import 'package:cross_file/cross_file.dart';
import 'package:cross_file_io/cross_file_io.dart';
import 'package:android_file_picker/android_file_picker.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
late Directory dir;
late String path;

setUpAll(CrossFileIO.registerWith);

setUp(() {
dir = Directory.systemTemp.createTempSync('file_picker_test');
path = '${dir.path}${Platform.pathSeparator}notes.txt';
File(path).writeAsStringSync('hello file_picker');
});

tearDown(() => dir.deleteSync(recursive: true));

test('reads a picked file through cross_file', () async {
final file = AndroidPlatformFile.fromMap({
'path': path,
'name': 'notes.txt',
});

expect(file.xFile, isA<FileSystemXFile>());
expect((file.xFile as FileSystemXFile).path, path);
expect(utf8.decode(await file.readAsBytes()), 'hello file_picker');
expect(
utf8.decode(await file.readAsByteStream().expand((c) => c).toList()),
'hello file_picker',
);
expect(await file.length(), 17);
});
}
5 changes: 5 additions & 0 deletions packages/file_picker_darwin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.0.0

- **BREAKING CHANGE**: Migrated to `cross_file` 0.4.0. `PlatformFile.xFile` now returns the new `XFile` API. Requires Flutter 3.41, Dart 3.11 and macOS 10.15. [#2224](https://github.com/vicajilau/flutter_file_picker/issues/2224)
- `DarwinOptions.acceptLabel` now also sets the confirm button text of `getDirectoryPath()` and `saveFile()` on macOS. [#1861](https://github.com/vicajilau/flutter_file_picker/issues/1861)

## 2.2.0

- Added support for `DarwinOptions.orderedSelection`. Setting it to `false` restores swipe to select in the iOS photo library picker, which ordered selection disables. [#2241](https://github.com/vicajilau/flutter_file_picker/issues/2241)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ iOS and macOS implementation of file_picker plugin
s.ios.dependency 'Flutter'
s.osx.dependency 'FlutterMacOS'
s.ios.deployment_target = '14.0'
s.osx.deployment_target = '10.13'
s.osx.deployment_target = '10.15'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.swift_version = '5.0'
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let package = Package(
name: "file_picker_darwin",
platforms: [
.iOS("14.0"),
.macOS("10.13")
.macOS("10.15")
],
products: [
.library(name: "file-picker-darwin", targets: ["file_picker_darwin"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ final class MacOSFilePickerHandler: NSObject, FlutterStreamHandler {
}
dialog.message = title
}
if let acceptLabel = args["acceptLabel"] as? String, !acceptLabel.isEmpty {
dialog.prompt = acceptLabel
}
dialog.showsHiddenFiles = false
dialog.allowsMultipleSelection = false
dialog.canChooseDirectories = true
Expand Down Expand Up @@ -269,6 +272,9 @@ final class MacOSFilePickerHandler: NSObject, FlutterStreamHandler {
dialog.canCreateDirectories = true
dialog.isExtensionHidden = true
dialog.nameFieldStringValue = args["fileName"] as? String ?? ""
if let acceptLabel = args["acceptLabel"] as? String, !acceptLabel.isEmpty {
dialog.prompt = acceptLabel
}

if let initialDirectory = args["initialDirectory"] as? String,
!initialDirectory.isEmpty {
Expand Down
14 changes: 5 additions & 9 deletions packages/file_picker_darwin/lib/src/darwin_platform_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ base class DarwinPlatformFile extends PlatformFile {
return DarwinPlatformFile(
name: name,
uri: uri,
xFile: path.isNotEmpty ? XFile(path, name: name) : null,
bytesLength: data['size'] as int?,
);
}
Expand All @@ -55,14 +54,11 @@ base class DarwinPlatformFile extends PlatformFile {
final int? _bytesLength;

@override
XFile get xFile {
final file = _xFile;
if (file != null) return file;
if (uri.scheme == 'file') {
return XFile(uri.toFilePath(), name: name);
}
return XFile(uri.toString(), name: name);
}
XFile get xFile =>
_xFile ??
(uri.scheme == 'file'
? XFile.fileSystem(path: uri.toFilePath())
: XFile.scopedStorage(uri: uri.toString()));

/// The size iOS/macOS already reported for this file when it was picked.
@override
Expand Down
Loading
Loading