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

Commit 2cbb314

Browse files
[image_picker] Allow saving photos picked with PHPicker without permissions (#6429)
1 parent 451f400 commit 2cbb314

File tree

7 files changed

+60
-23
lines changed

7 files changed

+60
-23
lines changed

packages/image_picker/image_picker_ios/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.8.6+1
2+
3+
* Fixes issue with crashing the app when picking images with PHPicker without providing `Photo Library Usage` permission.
4+
15
## 0.8.6
26

37
* Adds `requestFullMetadata` option to `pickImage`, so images on iOS can be picked without `Photo Library Usage` permission.

packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ - (void)testSaveWebPImage API_AVAILABLE(ios(14)) {
2222
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
2323
withIdentifier:UTTypeWebP.identifier];
2424

25-
[self verifySavingImageWithPickerResult:result];
25+
[self verifySavingImageWithPickerResult:result fullMetadata:YES];
2626
}
2727

2828
- (void)testSavePNGImage API_AVAILABLE(ios(14)) {
@@ -32,7 +32,7 @@ - (void)testSavePNGImage API_AVAILABLE(ios(14)) {
3232
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
3333
withIdentifier:UTTypeWebP.identifier];
3434

35-
[self verifySavingImageWithPickerResult:result];
35+
[self verifySavingImageWithPickerResult:result fullMetadata:YES];
3636
}
3737

3838
- (void)testSaveJPGImage API_AVAILABLE(ios(14)) {
@@ -42,7 +42,7 @@ - (void)testSaveJPGImage API_AVAILABLE(ios(14)) {
4242
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
4343
withIdentifier:UTTypeWebP.identifier];
4444

45-
[self verifySavingImageWithPickerResult:result];
45+
[self verifySavingImageWithPickerResult:result fullMetadata:YES];
4646
}
4747

4848
- (void)testSaveGIFImage API_AVAILABLE(ios(14)) {
@@ -52,7 +52,21 @@ - (void)testSaveGIFImage API_AVAILABLE(ios(14)) {
5252
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
5353
withIdentifier:UTTypeWebP.identifier];
5454

55-
[self verifySavingImageWithPickerResult:result];
55+
[self verifySavingImageWithPickerResult:result fullMetadata:YES];
56+
}
57+
58+
- (void)testSavePNGImageWithoutFullMetadata API_AVAILABLE(ios(14)) {
59+
id photoAssetUtil = OCMClassMock([PHAsset class]);
60+
61+
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"pngImage"
62+
withExtension:@"png"];
63+
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
64+
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
65+
withIdentifier:UTTypeWebP.identifier];
66+
67+
[self verifySavingImageWithPickerResult:result fullMetadata:NO];
68+
OCMVerify(times(0), [photoAssetUtil fetchAssetsWithLocalIdentifiers:[OCMArg any]
69+
options:[OCMArg any]]);
5670
}
5771

5872
/**
@@ -79,14 +93,16 @@ - (PHPickerResult *)createPickerResultWithProvider:(NSItemProvider *)itemProvide
7993
*
8094
* @param result the picker result
8195
*/
82-
- (void)verifySavingImageWithPickerResult:(PHPickerResult *)result API_AVAILABLE(ios(14)) {
96+
- (void)verifySavingImageWithPickerResult:(PHPickerResult *)result
97+
fullMetadata:(BOOL)fullMetadata API_AVAILABLE(ios(14)) {
8398
XCTestExpectation *pathExpectation = [self expectationWithDescription:@"Path was created"];
8499

85100
FLTPHPickerSaveImageToPathOperation *operation = [[FLTPHPickerSaveImageToPathOperation alloc]
86101
initWithResult:result
87102
maxHeight:@100
88103
maxWidth:@100
89104
desiredImageQuality:@100
105+
fullMetadata:fullMetadata
90106
savedPathBlock:^(NSString *savedPath) {
91107
if ([[NSFileManager defaultManager] fileExistsAtPath:savedPath]) {
92108
[pathExpectation fulfill];

packages/image_picker/image_picker_ios/example/lib/main.dart

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,15 @@ class _MyHomePageState extends State<MyHomePage> {
9393
await _displayPickImageDialog(context!,
9494
(double? maxWidth, double? maxHeight, int? quality) async {
9595
try {
96-
final List<XFile>? pickedFileList = await _picker.getMultiImage(
97-
maxWidth: maxWidth,
98-
maxHeight: maxHeight,
99-
imageQuality: quality,
96+
final List<XFile> pickedFileList =
97+
await _picker.getMultiImageWithOptions(
98+
options: MultiImagePickerOptions(
99+
imageOptions: ImageOptions(
100+
maxWidth: maxWidth,
101+
maxHeight: maxHeight,
102+
imageQuality: quality,
103+
),
104+
),
100105
);
101106
setState(() {
102107
_imageFileList = pickedFileList;
@@ -111,11 +116,13 @@ class _MyHomePageState extends State<MyHomePage> {
111116
await _displayPickImageDialog(context!,
112117
(double? maxWidth, double? maxHeight, int? quality) async {
113118
try {
114-
final XFile? pickedFile = await _picker.getImage(
119+
final XFile? pickedFile = await _picker.getImageFromSource(
115120
source: source,
116-
maxWidth: maxWidth,
117-
maxHeight: maxHeight,
118-
imageQuality: quality,
121+
options: ImagePickerOptions(
122+
maxWidth: maxWidth,
123+
maxHeight: maxHeight,
124+
imageQuality: quality,
125+
),
119126
);
120127
setState(() {
121128
_setImageFileListFromFile(pickedFile);

packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -490,14 +490,15 @@ - (void)picker:(PHPickerViewController *)picker
490490

491491
for (int i = 0; i < results.count; i++) {
492492
PHPickerResult *result = results[i];
493-
FLTPHPickerSaveImageToPathOperation *operation =
494-
[[FLTPHPickerSaveImageToPathOperation alloc] initWithResult:result
495-
maxHeight:maxHeight
496-
maxWidth:maxWidth
497-
desiredImageQuality:desiredImageQuality
498-
savedPathBlock:^(NSString *savedPath) {
499-
pathList[i] = savedPath;
500-
}];
493+
FLTPHPickerSaveImageToPathOperation *operation = [[FLTPHPickerSaveImageToPathOperation alloc]
494+
initWithResult:result
495+
maxHeight:maxHeight
496+
maxWidth:maxWidth
497+
desiredImageQuality:desiredImageQuality
498+
fullMetadata:self.callContext.requestFullMetadata
499+
savedPathBlock:^(NSString *savedPath) {
500+
pathList[i] = savedPath;
501+
}];
501502
[operationQueue addOperation:operation];
502503
}
503504
[operationQueue waitUntilAllOperationsAreFinished];

packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
maxHeight:(NSNumber *)maxHeight
2727
maxWidth:(NSNumber *)maxWidth
2828
desiredImageQuality:(NSNumber *)desiredImageQuality
29+
fullMetadata:(BOOL)fullMetadata
2930
savedPathBlock:(void (^)(NSString *))savedPathBlock API_AVAILABLE(ios(14));
3031

3132
@end

packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ @interface FLTPHPickerSaveImageToPathOperation ()
1313
@property(assign, nonatomic) NSNumber *maxHeight;
1414
@property(assign, nonatomic) NSNumber *maxWidth;
1515
@property(assign, nonatomic) NSNumber *desiredImageQuality;
16+
@property(assign, nonatomic) BOOL requestFullMetadata;
1617

1718
@end
1819

@@ -28,13 +29,15 @@ - (instancetype)initWithResult:(PHPickerResult *)result
2829
maxHeight:(NSNumber *)maxHeight
2930
maxWidth:(NSNumber *)maxWidth
3031
desiredImageQuality:(NSNumber *)desiredImageQuality
32+
fullMetadata:(BOOL)fullMetadata
3133
savedPathBlock:(GetSavedPath)savedPathBlock API_AVAILABLE(ios(14)) {
3234
if (self = [super init]) {
3335
if (result) {
3436
self.result = result;
3537
self.maxHeight = maxHeight;
3638
self.maxWidth = maxWidth;
3739
self.desiredImageQuality = desiredImageQuality;
40+
self.requestFullMetadata = fullMetadata;
3841
getSavedPath = savedPathBlock;
3942
executing = NO;
4043
finished = NO;
@@ -113,7 +116,12 @@ - (void)start {
113116
* Processes the image.
114117
*/
115118
- (void)processImage:(UIImage *)localImage API_AVAILABLE(ios(14)) {
116-
PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];
119+
PHAsset *originalAsset;
120+
// Only if requested, fetch the full "PHAsset" metadata, which requires "Photo Library Usage"
121+
// permissions.
122+
if (self.requestFullMetadata) {
123+
originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];
124+
}
117125

118126
if (self.maxWidth != nil || self.maxHeight != nil) {
119127
localImage = [FLTImagePickerImageUtil scaledImage:localImage

packages/image_picker/image_picker_ios/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: image_picker_ios
22
description: iOS implementation of the image_picker plugin.
33
repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_ios
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
5-
version: 0.8.6
5+
version: 0.8.6+1
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)