Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[image_picker] add requestFullMetadata for iOS (optional permissions) - platform interface changes for multi image picking #5914

Merged
Merged
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.6.0

* Deprecates `getMultiImage` in favor of a new method `getMultiImageWithOptions`.
* Adds `requestFullMetadata` option that allows disabling extra permission requests
on certain platforms.
* Moves optional image picking parameters to `MultiImagePickerOptions` class.

## 2.5.0

* Deprecates `getImage` in favor of a new method `getImageFromSource`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
import 'package:image_picker_platform_interface/src/types/multi_image_picker_options.dart';

const MethodChannel _channel = MethodChannel('plugins.flutter.io/image_picker');

Expand Down Expand Up @@ -57,6 +58,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform {
double? maxWidth,
double? maxHeight,
int? imageQuality,
bool requestFullMetadata = true,
}) {
if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) {
throw ArgumentError.value(
Expand All @@ -77,6 +79,7 @@ class MethodChannelImagePicker extends ImagePickerPlatform {
'maxWidth': maxWidth,
'maxHeight': maxHeight,
'imageQuality': imageQuality,
'requestFullMetadata': requestFullMetadata,
},
);
}
Expand Down Expand Up @@ -233,6 +236,23 @@ class MethodChannelImagePicker extends ImagePickerPlatform {
return paths.map((dynamic path) => XFile(path as String)).toList();
}

@override
Future<List<XFile>> getMultiImageWithOptions({
MultiImagePickerOptions options = const MultiImagePickerOptions(),
}) async {
final List<dynamic>? paths = await _getMultiImagePath(
maxWidth: options.imageOptions.maxWidth,
maxHeight: options.imageOptions.maxHeight,
imageQuality: options.imageOptions.imageQuality,
requestFullMetadata: options.imageOptions.requestFullMetadata,
);
if (paths == null) {
return <XFile>[];
}

return paths.map((dynamic path) => XFile(path as String)).toList();
}

@override
Future<XFile?> getVideo({
required ImageSource source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:async';

import 'package:cross_file/cross_file.dart';
import 'package:image_picker_platform_interface/src/method_channel/method_channel_image_picker.dart';
import 'package:image_picker_platform_interface/src/types/multi_image_picker_options.dart';
import 'package:image_picker_platform_interface/src/types/types.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

Expand Down Expand Up @@ -186,6 +187,8 @@ abstract class ImagePickerPlatform extends PlatformInterface {
throw UnimplementedError('getImage() has not been implemented.');
}

/// This method is deprecated in favor of [getMultiImageWithOptions] and will be removed in a future update.
///
/// Returns a [List<XFile>] with the images that were picked.
///
/// The images come from the [ImageSource.gallery].
Expand Down Expand Up @@ -283,4 +286,23 @@ abstract class ImagePickerPlatform extends PlatformInterface {
preferredCameraDevice: options.preferredCameraDevice,
);
}

/// Returns a [List<XFile>] with the images that were picked.
///
/// The images come from the [ImageSource.gallery].
///
/// The `options` argument controls additional settings that can be used when
/// picking an image. See [MultiImagePickerOptions] for more details.
///
/// If no images were picked, returns an empty list.
Future<List<XFile>> getMultiImageWithOptions({
MultiImagePickerOptions options = const MultiImagePickerOptions(),
}) async {
final List<XFile>? pickedImages = await getMultiImage(
maxWidth: options.imageOptions.maxWidth,
maxHeight: options.imageOptions.maxHeight,
imageQuality: options.imageOptions.imageQuality,
);
return pickedImages ?? <XFile>[];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Specifies image-specific options for picking.
class ImageOptions {
/// Creates an instance with the given [maxHeight], [maxWidth], [imageQuality]
/// and [requestFullMetadata].
const ImageOptions({
this.maxHeight,
this.maxWidth,
this.imageQuality,
this.requestFullMetadata = true,
});

/// The maximum width of the image, in pixels.
///
/// If null, the image will only be resized if [maxHeight] is specified.
final double? maxWidth;

/// The maximum height of the image, in pixels.
///
/// If null, the image will only be resized if [maxWidth] is specified.
final double? maxHeight;

/// Modifies the quality of the image, ranging from 0-100 where 100 is the
/// original/max quality.
///
/// Compression is only supported for certain image types such as JPEG. If
/// compression is not supported for the image that is picked, a warning
/// message will be logged.
///
/// If null, the image will be returned with the original quality.
final int? imageQuality;

/// If true, requests full image metadata, which may require extra permissions
/// on some platforms, (e.g., NSPhotoLibraryUsageDescription on iOS).
//
// Defaults to true.
final bool requestFullMetadata;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:image_picker_platform_interface/src/types/image_options.dart';

/// Specifies options for picking multiple images from the device's gallery.
class MultiImagePickerOptions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we would share this with ImagePickerOptions, and extract a shared class that has the elements that are image-specific (i.e., everything here), and then an outer class with anything else. We don't need to do another change to the singe-image version now, but we should prep for it by structuring this that way: all of the fields here should move to a new ImageOptions, and then MultiImagePickerOptions should have one ImageOptions field. Eventually we can switch the single-image version to use ImageOptions instead of these four fields too.

/// Creates an instance with the given [imageOptions].
const MultiImagePickerOptions({
this.imageOptions = const ImageOptions(),
});

/// The image-specific options for picking.
final ImageOptions imageOptions;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/i
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.5.0
version: 2.6.0

environment:
sdk: ">=2.12.0 <3.0.0"
Expand Down
Loading