A macOS platform implementation of image_picker
using the native system picker instead of the system open file dialog.
This package is an alternative to image_picker_macos
which uses file_selector
.
Note
This native picker depends on the photos in the Photos for MacOS App, which uses the Apple PhotosUI Picker, also known as PHPicker.
Default picker | Native picker |
---|---|
![]() |
![]() |
- 🚀 Seamless Integration
Effortlessly integrates with theimage_picker
package. Switch seamlessly betweenimage_picker_macos
and this native platform implementation without modifying existing code. - 🔒 No Permissions or Setup Required
Requires no runtime permission prompts or entitlement configuration. Everything works out of the box. - 📱 macOS Photos App
Enables picking images from the macOS Photos app, integrating with the Apple ecosystem and supporting photo imports from connected iOS devices. - 🛠️ Supports Image Options
Adds support for image arguments likemaxWidth
,maxHeight
, andimageQuality
—features not currently supported inimage_picker_macos
.
Run the following command to add the dependencies:
$ flutter pub add image_picker image_picker_macos native_image_picker_macos
image_picker
: The app-facing package for the Image Picker plugin which specifies the API used by Flutter apps.image_picker_macos
: The default macOS implementation ofimage_picker
, built onfile_selector
and usingNSOpenPanel
with appropriate file type filters set. Lacks image resizing/compression options but supports older macOS versions.native_image_picker_macos
: A macOS implementation ofimage_picker
, built onPHPickerViewController
which depends on the Photos for macOS App. Supports image resizing/compression options. Requires macOS 13.0+.
Using both image_picker_macos
and native_image_picker_macos
can enable user-level opt-in to switch between implementations if the user prefers to pick images from the photos app or the file system.
The platform implementation image_picker_macos
is required to ensure compatibility with macOS versions before 13.0, which is used as a fallback, in that case, it's necessary to setup image_picker_macos
.
Tip
After registering this implementation as outlined in the Usage section, you can use the image_picker
plugin as usual.
By default, this package doesn't replace the default implementation of image_picker
for macOS to avoid conflict with image_picker_macos
.
This implementation supports macOS 13 Ventura and later.
To apply this package only in case it's supported on the current macOS version:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await NativeImagePickerMacOS.registerWithIfSupported(); // ADD THIS LINE
runApp(const MainApp());
}
To checks if the current implementation of image_picker
is native_image_picker_macos
:
final bool isRegistered = NativeImagePickerMacOS.isRegistered();
// OR
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
final bool isRegistered = ImagePickerPlatform.instance is NativeImagePickerMacOS;
To checks if the current macOS version supports this implementation:
final bool isSupported = await NativeImagePickerMacOS().isSupported(); // Returns false on non-macOS platforms or if PHPicker is not supported on the current macOS version.
To switch between image_picker_macos
and native_image_picker_macos
implementations:
// NOTE: This code assumes the current target platform is macOS and native_image_picker_macos implementation is supported.
import 'package:image_picker_macos/image_picker_macos.dart';
import 'package:native_image_picker_macos/native_image_picker_macos.dart';
// To switch to image_picker_macos (supported on all macOS versions):
ImagePickerMacOS.registerWith();
// To switch to native_image_picker_macos (supported on macOS 13 and above):
NativeImagePickerMacOS.registerWith();
To open the macOS photos app:
<!-- TODO: This approach needs more consideration, also update the example (which has related TODO) -->
await NativeImagePickerMacOS().openPhotosApp();
// OR
final ImagePickerPlatform imagePickerImplementation = ImagePickerPlatform.instance;
if (imagePickerImplementation is NativeImagePickerMacOS) {
await imagePickerImplementation.openPhotosApp();
}
Tip
You can use NativeImagePickerMacOS.registerWith()
to register this implementation. However, this bypasses platform checks, which may result in runtime errors if the current platform is not macOS or if the macOS version is unsupported. Instead, use registerWithIfSupported()
if uncertain.
This package uses pigeon for platform communication with the platform host and mockito for mocking in unit tests and swift-format for formatting the Swift code.
$ dart run pigeon --input pigeons/messages.dart # To generate the required Dart and host-language code.
$ dart run build_runner build --delete-conflicting-outputs # To generate the mock classes.
$ swift-format format --in-place --recursive macos/native_image_picker_macos/Sources/native_image_picker_macos # To format the Swift code.
- Flutter repo style guide.
- Flutter repo plugin tests.
- Flutter repo writing effective tests.
- Flutter developing plugin packages.
- Flutter testing plugins, Flutter plugins in Flutter tests and Flutter mock dependencies using Mockito.
- Pigeon example README.
- Effective Dart.
- PHPickerViewController.
Contributions are welcome. File issues to the GitHub repo.
- Similarly to
image_picker_macos
,ImageSource.camera
is not supported unless acameraDelegate
is set. - Similarly to
image_picker_macos
, themaxDuration
argument inpickVideo
is unsupported and will be silently ignored.
Warning
Known issue: The native picker window initially appears smaller than expected, requiring the user to manually resize it. Refer to #2 for details.
This functionality was originally proposed as a pull request to image_picker_macos
, but it was later decided to split it into a community package which is unendorsed.