FlutterFever Studio
Back to packages

Image Picker Platform Interface Flutter package guide

A platform‑agnostic contract that defines how image_picker implementations communicate with Flutter.

Install command
Copy and run in your Flutter project
flutter pub add image_picker_platform_interface

When to use Image Picker Platform Interface

The **Image Picker Platform Interface** package supplies a clean, version‑stable contract that separates the public API of the popular `image_picker` plugin from its native implementations. In a federated plugin architecture, this interface lives in a pure‑Dart package, while platform‑specific code (Android, iOS, web, macOS, Linux, Windows) resides in separate packages that depend on it. By keeping the contract isolated, the Flutter ecosystem can evolve each implementation independently, reduce breaking changes, and allow developers to swap or extend the underlying picker without touching the UI layer. This approach mirrors the design of other first‑party plugins and encourages a modular, testable codebase.

When you are building a custom image‑selection solution—perhaps to add proprietary compression, integrate a corporate asset‑management system, or support a niche platform not covered by the default `image_picker`—the platform interface becomes your starting point. Instead of forking the entire plugin, you implement the abstract methods defined in this package, register your implementation with `ImagePickerPlatform.instance`, and let the rest of your app continue to call the familiar `pickImage` and `pickMultiImage` methods. This decoupling also benefits library authors who want to expose a consistent API across multiple platforms while delegating the heavy lifting to native code.

From an architectural perspective, the interface sits at the boundary between the Flutter UI layer and the host platform. The UI layer depends only on the abstract contract, making it agnostic to whether the image data comes from the device camera, a file picker, a cloud service, or a simulated test environment. The concrete implementation lives in a separate package that imports `image_picker_platform_interface` and provides the platform‑specific logic using method channels, Swift/Objective‑C, Kotlin/Java, or JavaScript. This separation aligns with clean‑architecture principles: the domain (your UI) does not know about the details of the infrastructure (native code), which simplifies unit testing and future refactoring.

To get started, add the package to your `pubspec.yaml` with the exact command: ``` flutter pub add image_picker_platform_interface ``` After the dependency is resolved, import the interface and either use the default implementation (provided by the official `image_picker` plugin) or register your own: ```dart import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';

class MyCustomPicker extends ImagePickerPlatform { @override Future<XFile?> pickImage({ required ImageSource source, CameraDevice preferredCameraDevice = CameraDevice.rear, ImagePickerOptions? options, }) async { // Insert native method‑channel call or custom logic here. return null; // Replace with actual XFile. } }

void main() { ImagePickerPlatform.instance = MyCustomPicker(); runApp(MyApp()); } ``` The example demonstrates how to swap the implementation at runtime, which is especially useful for testing or for providing platform‑specific features that the default plugin does not expose. Remember to also add the corresponding platform packages (e.g., `image_picker_android`, `image_picker_ios`) if you rely on the official implementations.

Production‑grade projects should pay attention to a few cautions. First, the interface follows semantic versioning, but breaking changes can still occur when the core `image_picker` plugin updates its contract; pinning a compatible version range in `pubspec.yaml` helps avoid surprises. Second, handling permissions is still the responsibility of the concrete implementation—ensure you request camera, gallery, or storage access on each platform before invoking the picker. Third, test your custom implementation on all target platforms, because method‑channel mismatches can surface only at runtime. Finally, consider performance implications of large image files; you may want to downscale or compress images in the native layer before returning them to Flutter.

For beginners, the most straightforward use case is to rely on the default implementation provided by the official `image_picker` plugin. By adding `image_picker_platform_interface` as a dependency, you gain the flexibility to replace the picker later without refactoring UI code. A simple UI button that calls `ImagePickerPlatform.instance.pickImage(source: ImageSource.gallery)` will work out of the box, while still keeping your codebase ready for advanced customizations. This makes the package a future‑proof foundation for any app that needs to let users select photos or videos, whether you stay with the default behavior or build a bespoke solution.

custom image picker implementation
testing image picker with mock platforms
extending image_picker for corporate asset pipelines
supporting new platforms not covered by the official plugin

Pros

  • stable contract isolates UI from native code
  • enables custom or mock implementations
  • supports all Flutter platforms
  • compatible with null‑safety and latest SDK

Watch outs

  • not a ready‑to‑use UI component
  • requires native code for full functionality
  • adds an extra layer of abstraction for simple apps

Setup notes

Run `flutter pub add image_picker_platform_interface` to add the dependency. Import the package with `import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';`. If you plan to use the default implementation, also add the concrete platform packages (e.g., `image_picker_android`, `image_picker_ios`). Register a custom implementation by assigning `ImagePickerPlatform.instance = YourPicker();` before calling any picker methods.

Requires Flutter SDK >=2.12.0. Supports Android, iOS, web, macOS, Linux, and Windows. Works with Dart null‑safety. Ensure that any native implementation you provide matches the platform's permission model and method‑channel signatures.

import 'package:flutter/material.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';

class MyCustomPicker extends ImagePickerPlatform {
  @override
  Future<XFile?> pickImage({
    required ImageSource source,
    CameraDevice preferredCameraDevice = CameraDevice.rear,
    ImagePickerOptions? options,
  }) async {
    // Custom native call or mock implementation.
    return null; // Replace with actual XFile.
  }
}

void main() {
  ImagePickerPlatform.instance = MyCustomPicker();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Image Picker Interface')),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              final file = await ImagePickerPlatform.instance.pickImage(
                source: ImageSource.gallery,
              );
              // Handle the selected file.
            },
            child: const Text('Pick Image'),
          ),
        ),
      ),
    );
  }
}

Official package resources