Skip to content

Commit

Permalink
[image_picker] Improve image_picker for iOS to handle more image types (
Browse files Browse the repository at this point in the history
flutter#6812)

* Improve image picker for ios to handle more image types

* Update release info

* different svg, remove raw test

* change pro raw image

* change pro raw image

* add error log

* fix formatting

* fix image identifiers in test

* get image type identifier from itemProvider in test
  • Loading branch information
vashworth committed Dec 16, 2022
1 parent 7efb5e8 commit 32dcbf3
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 27 deletions.
4 changes: 4 additions & 0 deletions packages/image_picker/image_picker_ios/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.6+2

* Fixes issue where selectable images of certain types (such as ProRAW images) could not be loaded.

## 0.8.6+1

* Fixes issue with crashing the app when picking images with PHPicker without providing `Photo Library Usage` permission.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@
680049382280F2B9006DD6AB /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */; };
7865C5E12941326F0010E17F /* bmpImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E02941326F0010E17F /* bmpImage.bmp */; };
7865C5E22941326F0010E17F /* bmpImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E02941326F0010E17F /* bmpImage.bmp */; };
7865C5E4294132D50010E17F /* svgImage.svg in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E3294132D50010E17F /* svgImage.svg */; };
7865C5E5294132D50010E17F /* svgImage.svg in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E3294132D50010E17F /* svgImage.svg */; };
7865C5E72941374F0010E17F /* heicImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E62941374F0010E17F /* heicImage.heic */; };
7865C5E82941374F0010E17F /* heicImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E62941374F0010E17F /* heicImage.heic */; };
7865C5EA294137960010E17F /* icoImage.ico in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E9294137960010E17F /* icoImage.ico */; };
7865C5EB294137960010E17F /* icoImage.ico in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E9294137960010E17F /* icoImage.ico */; };
7865C5ED294137AB0010E17F /* tiffImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5EC294137AB0010E17F /* tiffImage.tiff */; };
7865C5EE294137AB0010E17F /* tiffImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5EC294137AB0010E17F /* tiffImage.tiff */; };
7865C5FC294157BC0010E17F /* icnsImage.icns in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FB294157BB0010E17F /* icnsImage.icns */; };
7865C5FD294157BC0010E17F /* icnsImage.icns in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FB294157BB0010E17F /* icnsImage.icns */; };
7865C5FF294252A60010E17F /* proRawImage.dng in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FE294252A60010E17F /* proRawImage.dng */; };
7865C600294252A60010E17F /* proRawImage.dng in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FE294252A60010E17F /* proRawImage.dng */; };
86430DF9272D71E9002D9D6C /* gifImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 9FC8F0E8229FA49E00C8D58F /* gifImage.gif */; };
86E9A893272754860017E6E0 /* PickerSaveImageToPathOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 86E9A892272754860017E6E0 /* PickerSaveImageToPathOperationTests.m */; };
86E9A894272754A30017E6E0 /* webpImage.webp in Resources */ = {isa = PBXBuildFile; fileRef = 86E9A88F272747B90017E6E0 /* webpImage.webp */; };
Expand Down Expand Up @@ -81,6 +95,13 @@
6801C83A2555D726009DAF8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagePickerPluginTests.m; sourceTree = "<group>"; };
68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PhotoAssetUtilTests.m; sourceTree = "<group>"; };
7865C5E02941326F0010E17F /* bmpImage.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = bmpImage.bmp; sourceTree = "<group>"; };
7865C5E3294132D50010E17F /* svgImage.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = svgImage.svg; sourceTree = "<group>"; };
7865C5E62941374F0010E17F /* heicImage.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = heicImage.heic; sourceTree = "<group>"; };
7865C5E9294137960010E17F /* icoImage.ico */ = {isa = PBXFileReference; lastKnownFileType = image.ico; path = icoImage.ico; sourceTree = "<group>"; };
7865C5EC294137AB0010E17F /* tiffImage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = tiffImage.tiff; sourceTree = "<group>"; };
7865C5FB294157BB0010E17F /* icnsImage.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icnsImage.icns; sourceTree = "<group>"; };
7865C5FE294252A60010E17F /* proRawImage.dng */ = {isa = PBXFileReference; lastKnownFileType = file; path = proRawImage.dng; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -152,6 +173,13 @@
9FC8F0E8229FA49E00C8D58F /* gifImage.gif */,
680049362280F2B8006DD6AB /* jpgImage.jpg */,
680049352280F2B8006DD6AB /* pngImage.png */,
7865C5E02941326F0010E17F /* bmpImage.bmp */,
7865C5E62941374F0010E17F /* heicImage.heic */,
7865C5FB294157BB0010E17F /* icnsImage.icns */,
7865C5E9294137960010E17F /* icoImage.ico */,
7865C5FE294252A60010E17F /* proRawImage.dng */,
7865C5E3294132D50010E17F /* svgImage.svg */,
7865C5EC294137AB0010E17F /* tiffImage.tiff */,
);
path = TestImages;
sourceTree = "<group>";
Expand Down Expand Up @@ -361,10 +389,17 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7865C5E12941326F0010E17F /* bmpImage.bmp in Resources */,
7865C5E4294132D50010E17F /* svgImage.svg in Resources */,
86430DF9272D71E9002D9D6C /* gifImage.gif in Resources */,
7865C5FF294252A60010E17F /* proRawImage.dng in Resources */,
7865C5EA294137960010E17F /* icoImage.ico in Resources */,
7865C5E72941374F0010E17F /* heicImage.heic in Resources */,
86E9A894272754A30017E6E0 /* webpImage.webp in Resources */,
86E9A895272769130017E6E0 /* pngImage.png in Resources */,
7865C5FC294157BC0010E17F /* icnsImage.icns in Resources */,
86E9A896272769150017E6E0 /* jpgImage.jpg in Resources */,
7865C5ED294137AB0010E17F /* tiffImage.tiff in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -373,8 +408,15 @@
buildActionMask = 2147483647;
files = (
9FC8F0EC229FA68500C8D58F /* gifImage.gif in Resources */,
7865C5EE294137AB0010E17F /* tiffImage.tiff in Resources */,
7865C5E82941374F0010E17F /* heicImage.heic in Resources */,
7865C5FD294157BC0010E17F /* icnsImage.icns in Resources */,
680049382280F2B9006DD6AB /* pngImage.png in Resources */,
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */,
7865C5EB294137960010E17F /* icoImage.ico in Resources */,
7865C5E22941326F0010E17F /* bmpImage.bmp in Resources */,
7865C600294252A60010E17F /* proRawImage.dng in Resources */,
7865C5E5294132D50010E17F /* svgImage.svg in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ - (void)testSaveWebPImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"webpImage"
withExtension:@"webp"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
Expand All @@ -29,8 +28,7 @@ - (void)testSavePNGImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"pngImage"
withExtension:@"png"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
Expand All @@ -39,8 +37,7 @@ - (void)testSaveJPGImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"jpgImage"
withExtension:@"jpg"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
Expand All @@ -49,20 +46,80 @@ - (void)testSaveGIFImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"gifImage"
withExtension:@"gif"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveBMPImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"bmpImage"
withExtension:@"bmp"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveHEICImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"heicImage"
withExtension:@"heic"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveICNSImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"icnsImage"
withExtension:@"icns"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveICOImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"icoImage"
withExtension:@"ico"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveProRAWImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"proRawImage"
withExtension:@"dng"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveSVGImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"svgImage"
withExtension:@"svg"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSaveTIFFImage API_AVAILABLE(ios(14)) {
NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"tiffImage"
withExtension:@"tiff"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];
[self verifySavingImageWithPickerResult:result fullMetadata:YES];
}

- (void)testSavePNGImageWithoutFullMetadata API_AVAILABLE(ios(14)) {
id photoAssetUtil = OCMClassMock([PHAsset class]);

NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"pngImage"
withExtension:@"png"];
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider];

[self verifySavingImageWithPickerResult:result fullMetadata:NO];
OCMVerify(times(0), [photoAssetUtil fetchAssetsWithLocalIdentifiers:[OCMArg any]
Expand All @@ -76,11 +133,11 @@ - (void)testSavePNGImageWithoutFullMetadata API_AVAILABLE(ios(14)) {
* @param identifier local identifier of the asset
*/
- (PHPickerResult *)createPickerResultWithProvider:(NSItemProvider *)itemProvider
withIdentifier:(NSString *)identifier API_AVAILABLE(ios(14)) {
API_AVAILABLE(ios(14)) {
PHPickerResult *result = OCMClassMock([PHPickerResult class]);

OCMStub([result itemProvider]).andReturn(itemProvider);
OCMStub([result assetIdentifier]).andReturn(identifier);
OCMStub([result assetIdentifier]).andReturn(itemProvider.registeredTypeIdentifiers.firstObject);

return result;
}
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#import "FLTPHPickerSaveImageToPathOperation.h"

#import <os/log.h>

API_AVAILABLE(ios(14))
@interface FLTPHPickerSaveImageToPathOperation ()

Expand Down Expand Up @@ -88,25 +90,23 @@ - (void)start {
if (@available(iOS 14, *)) {
[self setExecuting:YES];

if ([self.result.itemProvider hasItemConformingToTypeIdentifier:UTTypeWebP.identifier]) {
// This supports uniform types that conform to UTTypeImage.
// This includes UTTypeHEIC, UTTypeHEIF, UTTypeLivePhoto, UTTypeICO, UTTypeICNS, UTTypePNG
// UTTypeGIF, UTTypeJPEG, UTTypeWebP, UTTypeTIFF, UTTypeBMP, UTTypeSVG, UTTypeRAWImage
if ([self.result.itemProvider hasItemConformingToTypeIdentifier:UTTypeImage.identifier]) {
[self.result.itemProvider
loadDataRepresentationForTypeIdentifier:UTTypeWebP.identifier
loadDataRepresentationForTypeIdentifier:UTTypeImage.identifier
completionHandler:^(NSData *_Nullable data,
NSError *_Nullable error) {
UIImage *image = [[UIImage alloc] initWithData:data];
[self processImage:image];
if (data != nil) {
UIImage *image = [[UIImage alloc] initWithData:data];
[self processImage:image];
} else {
os_log_error(OS_LOG_DEFAULT, "Could not process image: %@",
error);
}
}];
return;
}

[self.result.itemProvider
loadObjectOfClass:[UIImage class]
completionHandler:^(__kindof id<NSItemProviderReading> _Nullable image,
NSError *_Nullable error) {
if ([image isKindOfClass:[UIImage class]]) {
[self processImage:image];
}
}];
} else {
[self setFinished:YES];
}
Expand Down
2 changes: 1 addition & 1 deletion packages/image_picker/image_picker_ios/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: image_picker_ios
description: iOS implementation of the image_picker plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
version: 0.8.6+1
version: 0.8.6+2

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

0 comments on commit 32dcbf3

Please sign in to comment.