diff --git a/packages/image_picker/image_picker_ios/CHANGELOG.md b/packages/image_picker/image_picker_ios/CHANGELOG.md index 986f5c0ff6ca..bff6dd7394f2 100644 --- a/packages/image_picker/image_picker_ios/CHANGELOG.md +++ b/packages/image_picker/image_picker_ios/CHANGELOG.md @@ -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. diff --git a/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/project.pbxproj index 2847bfd85046..2c97bd1d667f 100644 --- a/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/project.pbxproj @@ -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 */; }; @@ -81,6 +95,13 @@ 6801C83A2555D726009DAF8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagePickerPluginTests.m; sourceTree = ""; }; 68F4B463228B3AB500C25614 /* PhotoAssetUtilTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PhotoAssetUtilTests.m; sourceTree = ""; }; + 7865C5E02941326F0010E17F /* bmpImage.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = bmpImage.bmp; sourceTree = ""; }; + 7865C5E3294132D50010E17F /* svgImage.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = svgImage.svg; sourceTree = ""; }; + 7865C5E62941374F0010E17F /* heicImage.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = heicImage.heic; sourceTree = ""; }; + 7865C5E9294137960010E17F /* icoImage.ico */ = {isa = PBXFileReference; lastKnownFileType = image.ico; path = icoImage.ico; sourceTree = ""; }; + 7865C5EC294137AB0010E17F /* tiffImage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = tiffImage.tiff; sourceTree = ""; }; + 7865C5FB294157BB0010E17F /* icnsImage.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icnsImage.icns; sourceTree = ""; }; + 7865C5FE294252A60010E17F /* proRawImage.dng */ = {isa = PBXFileReference; lastKnownFileType = file; path = proRawImage.dng; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -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 = ""; @@ -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; }; @@ -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; }; diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m index e04c4f2abb50..5594b9d4dc28 100644 --- a/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m +++ b/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m @@ -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]; } @@ -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]; } @@ -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]; } @@ -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] @@ -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; } diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/bmpImage.bmp b/packages/image_picker/image_picker_ios/example/ios/TestImages/bmpImage.bmp new file mode 100644 index 000000000000..553e765fb018 Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/bmpImage.bmp differ diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/heicImage.heic b/packages/image_picker/image_picker_ios/example/ios/TestImages/heicImage.heic new file mode 100644 index 000000000000..03f41f69cc82 Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/heicImage.heic differ diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/icnsImage.icns b/packages/image_picker/image_picker_ios/example/ios/TestImages/icnsImage.icns new file mode 100644 index 000000000000..db0fbb07a69b Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/icnsImage.icns differ diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/icoImage.ico b/packages/image_picker/image_picker_ios/example/ios/TestImages/icoImage.ico new file mode 100644 index 000000000000..30923c7b6435 Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/icoImage.ico differ diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/proRawImage.dng b/packages/image_picker/image_picker_ios/example/ios/TestImages/proRawImage.dng new file mode 100644 index 000000000000..7c3de76c86e2 Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/proRawImage.dng differ diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/svgImage.svg b/packages/image_picker/image_picker_ios/example/ios/TestImages/svgImage.svg new file mode 100644 index 000000000000..19d6af9f660e --- /dev/null +++ b/packages/image_picker/image_picker_ios/example/ios/TestImages/svgImage.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/packages/image_picker/image_picker_ios/example/ios/TestImages/tiffImage.tiff b/packages/image_picker/image_picker_ios/example/ios/TestImages/tiffImage.tiff new file mode 100644 index 000000000000..2431333c02e7 Binary files /dev/null and b/packages/image_picker/image_picker_ios/example/ios/TestImages/tiffImage.tiff differ diff --git a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m index 7c8fbc9ca7cf..16c205012785 100644 --- a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m +++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m @@ -6,6 +6,8 @@ #import "FLTPHPickerSaveImageToPathOperation.h" +#import + API_AVAILABLE(ios(14)) @interface FLTPHPickerSaveImageToPathOperation () @@ -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 _Nullable image, - NSError *_Nullable error) { - if ([image isKindOfClass:[UIImage class]]) { - [self processImage:image]; - } - }]; } else { [self setFinished:YES]; } diff --git a/packages/image_picker/image_picker_ios/pubspec.yaml b/packages/image_picker/image_picker_ios/pubspec.yaml index 6c78b2340ed0..e1b389161d75 100755 --- a/packages/image_picker/image_picker_ios/pubspec.yaml +++ b/packages/image_picker/image_picker_ios/pubspec.yaml @@ -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"