Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b1dfdcf
Default to image gallery when picking multiple images
mvanbeusekom Feb 1, 2022
9d15c59
Add additional unit-tests
mvanbeusekom Feb 1, 2022
bd955e9
Refactored tests to expose private interface in separate test header.
mvanbeusekom Feb 2, 2022
e8333f8
Adds declaration comments.
mvanbeusekom Feb 2, 2022
f60f73d
Fix spelling error in changelog
mvanbeusekom Feb 2, 2022
3921f8d
Fix formatting
mvanbeusekom Feb 3, 2022
2b5555a
Merged in unit test refactoring
mvanbeusekom Feb 3, 2022
8707cd8
Applied feedback from PR
mvanbeusekom Feb 3, 2022
441dea1
Refactored tests to expose private interface in separate test header.
mvanbeusekom Feb 2, 2022
6fc92d6
Adds declaration comments.
mvanbeusekom Feb 2, 2022
3a6d1b5
Fix spelling error in changelog
mvanbeusekom Feb 2, 2022
69a41d8
Fix formatting
mvanbeusekom Feb 3, 2022
31442f3
Remove private headers from umbrella
mvanbeusekom Feb 7, 2022
86a2987
Merge branch 'image_picker_test_header' into issue/96903
mvanbeusekom Feb 8, 2022
9b71661
Removes the pickImageWithUIImagePicker trampoline method.
mvanbeusekom Feb 8, 2022
76131a7
Use call.arguments instead of self.arguments.
mvanbeusekom Feb 8, 2022
84abc6f
Merge remote-tracking branch 'upstream/main' into issue/96903
mvanbeusekom Feb 8, 2022
35dc1ab
Merge remote-tracking branch 'upstream/main' into issue/96903
mvanbeusekom Feb 9, 2022
5ea21c7
Apply feedback on PR
mvanbeusekom Feb 9, 2022
134ba8b
Refactored FLTImagePickerPlugin not to be stateful
mvanbeusekom Feb 9, 2022
6bbd53c
Added declaration comments as required by style
mvanbeusekom Feb 9, 2022
f9bfe66
Apply fixes for nits
mvanbeusekom Feb 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/image_picker/image_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.8.4+8

* Ensures the `result` callback and method call `arguments` send to iOS are
taken into consideration when picking multiple images on pre-iOS 14 devices;
* Configures the `UIImagePicker` to default to gallery instead of camera when
picking multiple images on pre-iOS 14 devices.

## 0.8.4+7

* Refactors unit test to expose private interface via a separate test header instead of the inline declaration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,32 @@ - (void)testPluginPickVideoDeviceFront {
UIImagePickerControllerCameraDeviceFront);
}

- (void)testPickMultiImageShouldUseUIImagePickerControllerOnPreiOS14 {
if (@available(iOS 14, *)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@jmagman Relevant to our discussions about test matrixes in this repository: we won't ever actually test this in CI currently.

return;
}

id photoLibrary = OCMClassMock([PHPhotoLibrary class]);
OCMStub(ClassMethod([photoLibrary authorizationStatus]))
.andReturn(PHAuthorizationStatusAuthorized);

FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
[plugin setImagePickerControllerOverride:_mockUIImagePicker];
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"pickMultiImage"
arguments:@{
@"maxWidth" : @(100),
@"maxHeight" : @(200),
@"imageQuality" : @(50),
}];

[plugin handleMethodCall:call
result:^(id _Nullable r){
}];

OCMVerify(times(1),
[self->_mockUIImagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]);
}

#pragma mark - Test camera devices, no op on simulators

- (void)testPluginPickImageDeviceCancelClickMultipleTimes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ @interface FLTImagePickerPlugin () <UINavigationControllerDelegate,

@property(assign, nonatomic) int maxImagesAllowed;

@property(copy, nonatomic) NSDictionary *arguments;

@property(strong, nonatomic) PHPickerViewController *pickerViewController API_AVAILABLE(ios(14));

@end
Expand All @@ -45,6 +43,8 @@ @interface FLTImagePickerPlugin () <UINavigationControllerDelegate,
typedef NS_ENUM(NSInteger, ImagePickerClassType) { UIImagePickerClassType, PHPickerClassType };

@implementation FLTImagePickerPlugin {
NSDictionary *_arguments;
UIImagePickerController *_imagePickerControllerOverride;
UIImagePickerController *_imagePickerController;
}

Expand All @@ -56,10 +56,32 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
[registrar addMethodCallDelegate:instance channel:channel];
}

/**
* Initializes the _imagePickerController member with a new instance of the
* UIImagePickerController class.
*
* A new instance of the UIImagePickerController is created every time the
* initImagePickerController method is called. For testing purposes this can
* be overriden using the setImagePickerControllerOverride method, in which
* case the set instance of the UIImagePickerController is used to initialize
* the _imagePickerController member.
*/
- (void)initImagePickerController {
if (_imagePickerControllerOverride) {
_imagePickerController = _imagePickerControllerOverride;
} else {
_imagePickerController = [[UIImagePickerController alloc] init];
}
}

- (UIImagePickerController *)getImagePickerController {
return _imagePickerController;
}

- (void)setImagePickerControllerOverride:(UIImagePickerController *)imagePickerController {
_imagePickerControllerOverride = imagePickerController;
}

- (UIViewController *)viewControllerWithWindow:(UIWindow *)window {
UIWindow *windowToUse = window;
if (windowToUse == nil) {
Expand Down Expand Up @@ -108,14 +130,12 @@ - (void)pickImageWithPHPicker:(int)maxImagesAllowed API_AVAILABLE(ios(14)) {
[self checkPhotoAuthorizationForAccessLevel];
}

- (void)pickImageWithUIImagePicker {
_imagePickerController = [[UIImagePickerController alloc] init];
- (void)launchUIImagePickerWithSource:(int)imageSource {
[self initImagePickerController];
_imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
_imagePickerController.delegate = self;
_imagePickerController.mediaTypes = @[ (NSString *)kUTTypeImage ];

int imageSource = [[_arguments objectForKey:@"source"] intValue];

self.maxImagesAllowed = 1;

switch (imageSource) {
Expand All @@ -141,32 +161,31 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
self.result = nil;
}

self.result = result;
_arguments = call.arguments;

if ([@"pickImage" isEqualToString:call.method]) {
self.result = result;
_arguments = call.arguments;
int imageSource = [[_arguments objectForKey:@"source"] intValue];
int imageSource = [[call.arguments objectForKey:@"source"] intValue];

if (imageSource == SOURCE_GALLERY) { // Capture is not possible with PHPicker
if (@available(iOS 14, *)) {
// PHPicker is used
[self pickImageWithPHPicker:1];
} else {
// UIImagePicker is used
[self pickImageWithUIImagePicker];
[self launchUIImagePickerWithSource:imageSource];
}
} else {
[self pickImageWithUIImagePicker];
[self launchUIImagePickerWithSource:imageSource];
}
} else if ([@"pickMultiImage" isEqualToString:call.method]) {
if (@available(iOS 14, *)) {
self.result = result;
_arguments = call.arguments;
[self pickImageWithPHPicker:0];
} else {
[self pickImageWithUIImagePicker];
[self launchUIImagePickerWithSource:SOURCE_GALLERY];
}
} else if ([@"pickVideo" isEqualToString:call.method]) {
_imagePickerController = [[UIImagePickerController alloc] init];
[self initImagePickerController];
_imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
_imagePickerController.delegate = self;
_imagePickerController.mediaTypes = @[
Expand All @@ -175,12 +194,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
];
_imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;

self.result = result;
_arguments = call.arguments;

int imageSource = [[_arguments objectForKey:@"source"] intValue];
if ([[_arguments objectForKey:@"maxDuration"] isKindOfClass:[NSNumber class]]) {
NSTimeInterval max = [[_arguments objectForKey:@"maxDuration"] doubleValue];
int imageSource = [[call.arguments objectForKey:@"source"] intValue];
if ([[call.arguments objectForKey:@"maxDuration"] isKindOfClass:[NSNumber class]]) {
NSTimeInterval max = [[call.arguments objectForKey:@"maxDuration"] doubleValue];
_imagePickerController.videoMaximumDuration = max;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@
*/
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;

/**
* Sets the UIImagePickerController instance that should be used by the
* image_picker plugin.
*
* Should be used for testing purposes only.
*/
- (void)setImagePickerControllerOverride:(UIImagePickerController *)imagePickerController;

@end
2 changes: 1 addition & 1 deletion packages/image_picker/image_picker/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for selecting images from the Android and iOS image
library, and taking new pictures with the camera.
repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
version: 0.8.4+7
version: 0.8.4+8

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down