Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A macOS platform implementation of image_picker using the native system picker instead of file_selector

License

NotificationsYou must be signed in to change notification settings

CompileKernel/native-image-picker-macos

Repository files navigation

Pub VersionStar on GithubLicense: MITDart Code CoverageTests

A macOS platform implementation ofimage_pickerusing the native system picker instead of the system open file dialog.

This package is an alternative toimage_picker_macoswhich usesfile_selector.

Note

This native picker depends on the photos in thePhotos for MacOS App, which uses theApple PhotosUI Picker, also known as PHPicker.

Default pickerNative picker
Default pickermacOS PHPicker

✨ Features

  • 🚀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—featuresnot currently supported inimage_picker_macos.

Import photos from the connected iOS devices to macOS

🛠️ Getting started

Run the following command to add the dependencies:

$ flutter pub add image_picker image_picker_macos native_image_picker_macos
  1. image_picker: The app-facing package for the Image Picker plugin which specifies the API used by Flutter apps.
  2. 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.
  3. native_image_picker_macos: A macOS implementation ofimage_picker, built onPHPickerViewController which depends on thePhotos for macOS App. Supports image resizing/compression options. Requires macOS 13.0+.

Using bothimage_picker_macos andnative_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.

Use native macOS picker switch button

The platform implementationimage_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 tosetupimage_picker_macos.

Tip

After registering this implementation as outlined in theUsage section, you canuse theimage_picker plugin as usual.

📜 Usage

By default, this package doesn't replace the default implementation ofimage_picker for macOS to avoid conflict withimage_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();awaitNativeImagePickerMacOS.registerWithIfSupported();// ADD THIS LINErunApp(constMainApp());}

To checks if the current implementation ofimage_picker isnative_image_picker_macos:

finalbool isRegistered=NativeImagePickerMacOS.isRegistered();// ORimport'package:image_picker_platform_interface/image_picker_platform_interface.dart';finalbool isRegistered=ImagePickerPlatform.instanceisNativeImagePickerMacOS;

To checks if the current macOS version supports this implementation:

finalbool isSupported=awaitNativeImagePickerMacOS.isSupported();// Returns false on non-macOS platforms or if PHPicker is not supported on the current macOS version.

To switch betweenimage_picker_macos andnative_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:

awaitNativeImagePickerMacOS.instanceOrNull?.openPhotosApp();// ORfinalImagePickerPlatform imagePickerImplementation=ImagePickerPlatform.instance;if (imagePickerImplementationisNativeImagePickerMacOS) {await imagePickerImplementation.openPhotosApp();}

Tip

You can useNativeImagePickerMacOS.registerWith() to register this implementation. However, this bypasses platform checks, whichmay result in runtime errors if the current platform is not macOS or if the macOS version is unsupported. Instead, useregisterWithIfSupported() if uncertain.

Refer to theexample main.dart for a full usage example.

🌱 Contributing

This package usespigeon for platform communication with the platform host andmockito for mocking in unit tests andswift-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 example/macos/Runner example/macos/RunnerTests example/macos/RunnerUITests# To format the Swift code.$ dart format.# To format the Dart code.$ (cd example/macos&& xcodebuildtest -workspace Runner.xcworkspace -scheme Runner -configuration Debug -quiet)# To run the native macOS unit tests.$ fluttertest# To run the Flutter unit tests.

Resources

Contributions are welcome. File issues to theGitHub repo.

ℹ️ Limitations

📚 Additional information

This functionality was originally proposed as apull request toimage_picker_macos, but it was later decided to split it into a community package which is unendorsed.

PHPicker window

Ask a question about using the package.

🧪 Testing

Tip

With this approach, you can effectively test this platform implementation with the existing packages that useimage_picker APIs. All platform-specific calls toNativeImagePickerMacOS should use the instance fromImagePickerPlatform.instance instead of creating a newNativeImagePickerMacOS to work.

To override the methods implementation for unit testing, add the dev dependencies:

  1. mockito (ormocktail): for mocking the instance methods ofNativeImagePickerMacOS.
  2. image_picker_platform_interface: for overriding the instance ofImagePickerPlatform with the mock instance.
  3. build_runner: for creating the generated Dart files.
  4. plugin_platform_interface: SinceImagePickerPlatform extendsPlatformInterface, it's required to apply the mixinMockPlatformInterfaceMixin to the mock ofNativeImagePickerMacOS toignore an assertation failure that enforces the usage ofextends instead ofimplements, since mock classes need to extendMock and implement the real class.
$ flutter pub add dev:mockito dev:image_picker_platform_interface dev:build_runner dev:plugin_platform_interface# Add them as dev-dependencies

In your test file, add this annotation somewhere:

import'package:mockito/annotations.dart';import'package:mockito/mockito.dart';import'package:native_image_picker_macos/native_image_picker_macos.dart';@GenerateNiceMocks([MockSpec<NativeImagePickerMacOS>()])

Generate theMockNativeImagePickerMacOS by running:

$ dart run build_runner build --delete-conflicting-outputs

Create a new instance ofMockNativeImagePickerMacOS and override the instance ofImagePickerPlatform to every test:

import'package:image_picker_platform_interface/image_picker_platform_interface.dart';import'package:flutter_test/flutter_test.dart';voidmain() {TestWidgetsFlutterBinding.ensureInitialized();lateMockNativeImagePickerMacOS mockNativeImagePickerMacOS;setUp(() {    mockNativeImagePickerMacOS=MockNativeImagePickerMacOS();ImagePickerPlatform.instance= mockNativeImagePickerMacOS;  });// Your tests, example:testWidgets('pressing the open photos button calls openPhotosApp from $NativeImagePickerMacOS',    (WidgetTester tester)async {await tester          .pumpWidget(constExampleWidget());// REPLACE WITH THE TARGET WIDGETfinal openPhotosFinder=          find.text('Open Photos App');// REPLACE WITH THE BUTTON TEXTexpect(openPhotosFinder, findsOneWidget);// Assuming the openPhotosApp call will success.when(mockNativeImagePickerMacOS.openPhotosApp())          .thenAnswer((_)async=>true);await tester.tap(openPhotosFinder);await tester.pump();verify(mockNativeImagePickerMacOS.openPhotosApp()).called(1);verifyNoMoreInteractions(mockNativeImagePickerMacOS);    },  );// ...}

However, if you run the tests, you will get the following error:

 Assertion failed: "Platform interfaces must not be implemented with `implements`"

And that is because by default, all plugin platform interfaces that inherit fromPlatformInterface mustextends and notimplements it to avoid breaking changes (adding new methods to platform interfaces are not considered breaking changes).

And mock classes mustimplements the real class rather thanextends them, a solution is toprovide the mixinMockPlatformInterfaceMixin fromplugin_platform_interface that will override this check:

import'package:plugin_platform_interface/plugin_platform_interface.dart';// This doesn't work yet since MockNativeImagePickerMacOS is generated, unlike the mocktail package.classMockNativeImagePickerMacOSextendsMockwithMockPlatformInterfaceMixinimplementsNativeImagePickerMacOS {}

And sinceMockNativeImagePickerMacOS is generated, we need a new class that extends the base mock and provides theMockPlatformInterfaceMixin forplugin_platform_interface to not throw the assertion failure:

@GenerateNiceMocks([MockSpec<NativeImagePickerMacOS>(as:Symbol('BaseMockNativeImagePickerMacOS'))])// This name should be different than MockNativeImagePickerMacOS for the mockito generation to successimport'<current-test-file-name>.mocks.dart';// REPLACE <current-test-file-name> with the current test file name without extensionimport'package:plugin_platform_interface/plugin_platform_interface.dart';classMockNativeImagePickerMacOSextendsBaseMockNativeImagePickerMacOSwithMockPlatformInterfaceMixin {}// Use MockNativeImagePickerMacOS instead of BaseMockNativeImagePickerMacOS for creating the mock of NativeImagePickerMacOS

Refer to theexample main_test.dart for the full example test.

About

A macOS platform implementation of image_picker using the native system picker instead of file_selector

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp