Flutter Album Picker + Camera

Open-source Flutter plugin for a complete iOS photo attachment flow: ordered album selection, a built-in custom camera, flying thumbnail animation, pending and upload states, retry, removal, and temporary-file delivery to Dart.

Inline ordered photo album picker Built-in custom camera

Expandable camera and volume-button shutter walkthrough Complete picker, camera, and attachment walkthrough

Features

  • Inline SwiftUI photo-library sheet instead of a generic source menu
  • Ordered selection for up to a caller-defined photo limit
  • Built-in AVFoundation camera without leaving the picker
  • Rear/front camera switching and flash controls
  • Hardware shutter capture with either volume button on iOS 17.2 or newer
  • Camera sheet expands from medium to large for a bigger active preview
  • Glass back, camera, capture, and confirmation controls
  • Direct album or camera startup from Flutter
  • Add-only photo-library permission for captured photos
  • Original-quality temporary files returned through a small Dart API
  • Spring-based flying and shrinking animation into pending thumbnails
  • Pluggable upload callback with progress, completion, failure, and retry states
  • Optional remote removal callback with local-only operation when no backend exists

Requirements

  • Flutter 3.24 or newer
  • Dart 3.5 or newer
  • iOS 17 or newer
  • Swift 5.9

Install

Add the Git dependency:

dependencies:
  flutter_album_picker_camera:
    git:
      url: https://github.com/un1xr00t/flutter-album-picker-camera.git

Add these keys to the consuming app's Info.plist:

<key>NSCameraUsageDescription</key>
<string>Take photos inside the app.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Save photos taken inside the app.</string>

The system Photos picker does not require full photo-library permission. Captured photos request add-only library access.

While the camera is active and ready, either volume button triggers the same capture path as the onscreen shutter. The sheet opens at medium height and can be dragged upward for a larger live preview. iOS 17.0 and 17.1 keep the onscreen shutter without hardware-button capture.

Complete attachment flow

Drop the flow widget anywhere in a Flutter screen. It renders the add control, thumbnails, animation, upload progress, retry, and removal UI.

AlbumPickerAttachmentFlow<String>(
  onUpload: (photo, onProgress) async {
    return uploadPhoto(
      photo.path,
      filename: photo.name,
      onProgress: onProgress,
    );
  },
  onRemoved: (attachment) async {
    await deletePhoto(attachment.uploadResult!);
  },
  onChanged: (attachments) {
    final completed = attachments.where((item) => item.isComplete).toList();
  },
  onError: (error, stackTrace) {
    debugPrint('Photo flow failed: $error');
  },
)

The upload callback is the only app-specific boundary. Keep API URLs, authentication, persistence, and backend models in the consuming app. Omit onUpload for a complete local-only flow.

Low-level picker

Use the low-level API when the app already owns its attachment UI.

final photos = await FlutterAlbumPickerCamera.pickPhotos(
  limit: 24,
  startSource: AlbumPickerStartSource.album,
);

for (final photo in photos) {
  print(photo.path);
}

Use AlbumPickerStartSource.camera to open directly into the built-in camera.

Returned files live in the iOS temporary directory. Copy any file that must survive OS cleanup into application storage.

Current platform scope

iOS only. Android intentionally has no implementation yet.

License

Released under the MIT License. See LICENSE.