diff --git a/packages/image_picker/image_picker_ios/CHANGELOG.md b/packages/image_picker/image_picker_ios/CHANGELOG.md index 48d03e7bccbe..9720dba0a305 100644 --- a/packages/image_picker/image_picker_ios/CHANGELOG.md +++ b/packages/image_picker/image_picker_ios/CHANGELOG.md @@ -1,6 +1,10 @@ +## 0.8.6+5 + +* Fixes crash when `imageQuality` is set. + ## 0.8.6+4 -* Fix authorization status check for iOS14+ so it includes `PHAuthorizationStatusLimited`. +* Fixes authorization status check for iOS14+ so it includes `PHAuthorizationStatusLimited`. ## 0.8.6+3 diff --git a/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 9b24f28c25cc..3504e6812840 100755 --- a/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -47,16 +47,6 @@ ReferencedContainer = "container:Runner.xcodeproj"> - - - - *_Nullable result, FlutterError *_Nullable error){ }]; @@ -193,7 +193,7 @@ - (void)testPickImageWithoutFullMetadata API_AVAILABLE(ios(11)) { camera:FLTSourceCameraFront] maxSize:[[FLTMaxSize alloc] init] quality:nil - fullMetadata:@(NO) + fullMetadata:@NO completion:^(NSString *_Nullable result, FlutterError *_Nullable error){ }]; @@ -209,7 +209,7 @@ - (void)testPickMultiImageWithoutFullMetadata API_AVAILABLE(ios(11)) { [plugin pickMultiImageWithMaxSize:[[FLTMaxSize alloc] init] quality:nil - fullMetadata:@(NO) + fullMetadata:@NO completion:^(NSArray *_Nullable result, FlutterError *_Nullable error){ }]; @@ -231,7 +231,7 @@ - (void)testPluginPickImageDeviceCancelClickMultipleTimes { camera:FLTSourceCameraRear] maxSize:[[FLTMaxSize alloc] init] quality:nil - fullMetadata:@(YES) + fullMetadata:@YES completion:^(NSString *_Nullable result, FlutterError *_Nullable error){ }]; 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 d418354f5cc4..091755ca163b 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 @@ -184,7 +184,6 @@ - (void)testSavePNGImageWithoutFullMetadata API_AVAILABLE(ios(14)) { * Creates a mock picker result using NSItemProvider. * * @param itemProvider an item provider that will be used as picker result - * @param identifier local identifier of the asset */ - (PHPickerResult *)createPickerResultWithProvider:(NSItemProvider *)itemProvider API_AVAILABLE(ios(14)) { diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m index e081cee9cce4..dc5693b28603 100644 --- a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m +++ b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m @@ -59,41 +59,25 @@ - (void)tearDown { [self.app terminate]; } -- (void)testPickingFromGallery { - [self launchPickerAndPick]; -} - - (void)testCancel { - [self launchPickerAndCancel]; -} - -- (void)launchPickerAndCancel { // Find and tap on the pick from gallery button. - NSPredicate *predicateToFindImageFromGalleryButton = - [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_from_gallery"]; - XCUIElement *imageFromGalleryButton = - [self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton]; + self.app.otherElements[@"image_picker_example_from_gallery"].firstMatch; if (![imageFromGalleryButton waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find image from gallery button with %@ seconds", @(kElementWaitingTime)); } - XCTAssertTrue(imageFromGalleryButton.exists); [imageFromGalleryButton tap]; // Find and tap on the `pick` button. - NSPredicate *predicateToFindPickButton = - [NSPredicate predicateWithFormat:@"label == %@", @"PICK"]; - - XCUIElement *pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton]; + XCUIElement *pickButton = self.app.buttons[@"PICK"].firstMatch; if (![pickButton waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(kElementWaitingTime)); } - XCTAssertTrue(pickButton.exists); [pickButton tap]; // There is a known bug where the permission popups interruption won't get fired until a tap @@ -101,61 +85,70 @@ - (void)launchPickerAndCancel { [self.app tap]; // Find and tap on the `Cancel` button. - NSPredicate *predicateToFindCancelButton = - [NSPredicate predicateWithFormat:@"label == %@", @"Cancel"]; - - XCUIElement *cancelButton = - [self.app.buttons elementMatchingPredicate:predicateToFindCancelButton]; + XCUIElement *cancelButton = self.app.buttons[@"Cancel"].firstMatch; if (![cancelButton waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find Cancel button with %@ seconds", @(kElementWaitingTime)); } - XCTAssertTrue(cancelButton.exists); [cancelButton tap]; // Find the "not picked image text". - XCUIElement *imageNotPickedText = [self.app.staticTexts - elementMatchingPredicate:[NSPredicate - predicateWithFormat:@"label == %@", - @"You have not yet picked an image."]]; + XCUIElement *imageNotPickedText = + self.app.staticTexts[@"You have not yet picked an image."].firstMatch; if (![imageNotPickedText waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find imageNotPickedText with %@ seconds", @(kElementWaitingTime)); } +} - XCTAssertTrue(imageNotPickedText.exists); +- (void)testPickingFromGallery { + [self launchPickerAndPickWithMaxWidth:nil maxHeight:nil quality:nil]; } -- (void)launchPickerAndPick { - // Find and tap on the pick from gallery button. - NSPredicate *predicateToFindImageFromGalleryButton = - [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_from_gallery"]; +- (void)testPickingWithContraintsFromGallery { + [self launchPickerAndPickWithMaxWidth:@200 maxHeight:@100 quality:@50]; +} +- (void)launchPickerAndPickWithMaxWidth:(NSNumber *)maxWidth + maxHeight:(NSNumber *)maxHeight + quality:(NSNumber *)quality { + // Find and tap on the pick from gallery button. XCUIElement *imageFromGalleryButton = - [self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton]; + self.app.otherElements[@"image_picker_example_from_gallery"].firstMatch; if (![imageFromGalleryButton waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find image from gallery button with %@ seconds", @(kElementWaitingTime)); } - - XCTAssertTrue(imageFromGalleryButton.exists); [imageFromGalleryButton tap]; - // Find and tap on the `pick` button. - NSPredicate *predicateToFindPickButton = - [NSPredicate predicateWithFormat:@"label == %@", @"PICK"]; + if (maxWidth != nil) { + XCUIElement *field = self.app.textFields[@"Enter maxWidth if desired"].firstMatch; + [field tap]; + [field typeText:maxWidth.stringValue]; + } + + if (maxHeight != nil) { + XCUIElement *field = self.app.textFields[@"Enter maxHeight if desired"].firstMatch; + [field tap]; + [field typeText:maxHeight.stringValue]; + } - XCUIElement *pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton]; + if (quality != nil) { + XCUIElement *field = self.app.textFields[@"Enter quality if desired"].firstMatch; + [field tap]; + [field typeText:quality.stringValue]; + } + + // Find and tap on the `pick` button. + XCUIElement *pickButton = self.app.buttons[@"PICK"].firstMatch; if (![pickButton waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find pick button with %@ seconds", @(kElementWaitingTime)); } - - XCTAssertTrue(pickButton.exists); [pickButton tap]; // There is a known bug where the permission popups interruption won't get fired until a tap @@ -167,8 +160,7 @@ - (void)launchPickerAndPick { if (@available(iOS 14, *)) { aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; } else { - XCUIElement *allPhotosCell = [self.app.cells - elementMatchingPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"All Photos"]]; + XCUIElement *allPhotosCell = self.app.cells[@"All Photos"].firstMatch; if (![allPhotosCell waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find \"All Photos\" cell with %@ seconds", @@ -184,20 +176,14 @@ - (void)launchPickerAndPick { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime)); } - XCTAssertTrue(aImage.exists); [aImage tap]; // Find the picked image. - NSPredicate *predicateToFindPickedImage = - [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_picked_image"]; - - XCUIElement *pickedImage = [self.app.images elementMatchingPredicate:predicateToFindPickedImage]; + XCUIElement *pickedImage = self.app.images[@"image_picker_example_picked_image"].firstMatch; if (![pickedImage waitForExistenceWithTimeout:kElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find pickedImage with %@ seconds", @(kElementWaitingTime)); } - - XCTAssertTrue(pickedImage.exists); } @end diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m index 455fd6269d4b..7cce0520215b 100644 --- a/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m +++ b/packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m @@ -46,126 +46,67 @@ - (void)tearDown { [self.app terminate]; } -- (void)testSelectingFromGallery { - // Test the `Select Photos` button which is available after iOS 14. - if (@available(iOS 14, *)) { - [self launchPickerAndSelect]; - } else { - return; - } -} - -- (void)launchPickerAndSelect { +// Test the `Select Photos` button which is available after iOS 14. +- (void)testSelectingFromGallery API_AVAILABLE(ios(14)) { // Find and tap on the pick from gallery button. - NSPredicate *predicateToFindImageFromGalleryButton = - [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_from_gallery"]; - XCUIElement *imageFromGalleryButton = - [self.app.otherElements elementMatchingPredicate:predicateToFindImageFromGalleryButton]; + self.app.otherElements[@"image_picker_example_from_gallery"].firstMatch; if (![imageFromGalleryButton waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find image from gallery button with %@ seconds", @(kLimitedElementWaitingTime)); } - - XCTAssertTrue(imageFromGalleryButton.exists); [imageFromGalleryButton tap]; // Find and tap on the `pick` button. - NSPredicate *predicateToFindPickButton = - [NSPredicate predicateWithFormat:@"label == %@", @"PICK"]; - - XCUIElement *pickButton = [self.app.buttons elementMatchingPredicate:predicateToFindPickButton]; + XCUIElement *pickButton = self.app.buttons[@"PICK"].firstMatch; if (![pickButton waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTSkip(@"Pick button isn't found so the test is skipped..."); } - - XCTAssertTrue(pickButton.exists); [pickButton tap]; // There is a known bug where the permission popups interruption won't get fired until a tap // happened in the app. We expect a permission popup so we do a tap here. [self.app tap]; - // Find an image and tap on it. (IOS 14 UI, images are showing directly) - XCUIElement *aImage; - if (@available(iOS 14, *)) { - aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; - } else { - XCUIElement *selectedPhotosCell = [self.app.cells - elementMatchingPredicate:[NSPredicate - predicateWithFormat:@"label == %@", @"Selected Photos"]]; - if (![selectedPhotosCell waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { - os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); - XCTFail(@"Failed due to not able to find \"Selected Photos\" cell with %@ seconds", - @(kLimitedElementWaitingTime)); - } - [selectedPhotosCell tap]; - aImage = [self.app.collectionViews elementMatchingType:XCUIElementTypeCollectionView - identifier:@"PhotosGridView"] - .cells.firstMatch; - } + // Find an image and tap on it. + XCUIElement *aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kLimitedElementWaitingTime)); } - XCTAssertTrue(aImage.exists); + [aImage tap]; // Find and tap on the `Done` button. - NSPredicate *predicateToFindDoneButton = - [NSPredicate predicateWithFormat:@"label == %@", @"Done"]; - - XCUIElement *doneButton = [self.app.buttons elementMatchingPredicate:predicateToFindDoneButton]; + XCUIElement *doneButton = self.app.buttons[@"Done"].firstMatch; if (![doneButton waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTSkip(@"Permissions popup could not fired so the test is skipped..."); } - - XCTAssertTrue(doneButton.exists); [doneButton tap]; // Find an image and tap on it to have access to selected photos. - if (@available(iOS 14, *)) { - aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; - } else { - XCUIElement *selectedPhotosCell = [self.app.cells - elementMatchingPredicate:[NSPredicate - predicateWithFormat:@"label == %@", @"Selected Photos"]]; - if (![selectedPhotosCell waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { - os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); - XCTFail(@"Failed due to not able to find \"Selected Photos\" cell with %@ seconds", - @(kLimitedElementWaitingTime)); - } - [selectedPhotosCell tap]; - aImage = [self.app.collectionViews elementMatchingType:XCUIElementTypeCollectionView - identifier:@"PhotosGridView"] - .cells.firstMatch; - } + aImage = [self.app.scrollViews.firstMatch.images elementBoundByIndex:1]; + os_log_error(OS_LOG_DEFAULT, "description before picking image %@", self.app.debugDescription); if (![aImage waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kLimitedElementWaitingTime)); } - XCTAssertTrue(aImage.exists); [aImage tap]; // Find the picked image. - NSPredicate *predicateToFindPickedImage = - [NSPredicate predicateWithFormat:@"label == %@", @"image_picker_example_picked_image"]; - - XCUIElement *pickedImage = [self.app.images elementMatchingPredicate:predicateToFindPickedImage]; + XCUIElement *pickedImage = self.app.images[@"image_picker_example_picked_image"].firstMatch; if (![pickedImage waitForExistenceWithTimeout:kLimitedElementWaitingTime]) { os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription); XCTFail(@"Failed due to not able to find pickedImage with %@ seconds", @(kLimitedElementWaitingTime)); } - - XCTAssertTrue(pickedImage.exists); } @end diff --git a/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerImageUtil.m b/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerImageUtil.m index d5b823cf90a1..6adfd50402af 100644 --- a/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerImageUtil.m +++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerImageUtil.m @@ -116,7 +116,7 @@ + (GIFInfo *)scaledGIFImage:(NSData *)data maxWidth:(NSNumber *)maxWidth maxHeight:(NSNumber *)maxHeight { NSMutableDictionary *options = [NSMutableDictionary dictionary]; - options[(NSString *)kCGImageSourceShouldCache] = @(YES); + options[(NSString *)kCGImageSourceShouldCache] = @YES; options[(NSString *)kCGImageSourceTypeIdentifierHint] = (NSString *)kUTTypeGIF; CGImageSourceRef imageSource = 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 9a4ae2fb00fd..11fedfb73846 100644 --- a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m +++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m @@ -13,9 +13,9 @@ @interface FLTPHPickerSaveImageToPathOperation () @property(strong, nonatomic) PHPickerResult *result; -@property(assign, nonatomic) NSNumber *maxHeight; -@property(assign, nonatomic) NSNumber *maxWidth; -@property(assign, nonatomic) NSNumber *desiredImageQuality; +@property(strong, nonatomic) NSNumber *maxHeight; +@property(strong, nonatomic) NSNumber *maxWidth; +@property(strong, nonatomic) NSNumber *desiredImageQuality; @property(assign, nonatomic) BOOL requestFullMetadata; @end diff --git a/packages/image_picker/image_picker_ios/pubspec.yaml b/packages/image_picker/image_picker_ios/pubspec.yaml index e8ebcfd3756c..91d96c3d0a20 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+4 +version: 0.8.6+5 environment: sdk: ">=2.14.0 <3.0.0"