Skip to content

Commit f9bd733

Browse files
authored
[image_picker_ios] Add photo to simulator Photos library during test (#9759)
The iOS 26 simulator Photos library does not pre-populate example images. When the example app launches, add a test photo to the library. Only add a photo on first launch of the example app, enforced for a `NSUserDefault`. Fixes flutter/flutter#173327 ## Pre-Review Checklist **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 01d4c31 commit f9bd733

File tree

5 files changed

+75
-22
lines changed

5 files changed

+75
-22
lines changed

packages/image_picker/image_picker_ios/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## NEXT
22

33
* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.
4+
* Adds photo to Photos library during test to support iOS 26.
45

56
## 0.8.12+2
67

packages/image_picker/image_picker_ios/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,14 @@
1515
3A72BAD3FAE6E0FA9D80826B /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35AE65F25E0B8C8214D8372B /* libPods-RunnerTests.a */; };
1616
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
1717
5C9513011EC38BD300040975 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C9513001EC38BD300040975 /* GeneratedPluginRegistrant.m */; };
18-
680049382280F2B9006DD6AB /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
19-
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
2018
6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */; };
2119
782C2B45299ECE33008DC703 /* jpgImageWithRightOrientation.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 782C2B44299ECE33008DC703 /* jpgImageWithRightOrientation.jpg */; };
22-
782C2B46299ECE33008DC703 /* jpgImageWithRightOrientation.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 782C2B44299ECE33008DC703 /* jpgImageWithRightOrientation.jpg */; };
2320
7865C5E12941326F0010E17F /* bmpImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E02941326F0010E17F /* bmpImage.bmp */; };
24-
7865C5E22941326F0010E17F /* bmpImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E02941326F0010E17F /* bmpImage.bmp */; };
2521
7865C5E72941374F0010E17F /* heicImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E62941374F0010E17F /* heicImage.heic */; };
26-
7865C5E82941374F0010E17F /* heicImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E62941374F0010E17F /* heicImage.heic */; };
2722
7865C5EA294137960010E17F /* icoImage.ico in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E9294137960010E17F /* icoImage.ico */; };
28-
7865C5EB294137960010E17F /* icoImage.ico in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E9294137960010E17F /* icoImage.ico */; };
2923
7865C5ED294137AB0010E17F /* tiffImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5EC294137AB0010E17F /* tiffImage.tiff */; };
30-
7865C5EE294137AB0010E17F /* tiffImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5EC294137AB0010E17F /* tiffImage.tiff */; };
3124
7865C5FC294157BC0010E17F /* icnsImage.icns in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FB294157BB0010E17F /* icnsImage.icns */; };
32-
7865C5FD294157BC0010E17F /* icnsImage.icns in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FB294157BB0010E17F /* icnsImage.icns */; };
3325
7865C5FF294252A60010E17F /* proRawImage.dng in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FE294252A60010E17F /* proRawImage.dng */; };
34-
7865C600294252A60010E17F /* proRawImage.dng in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FE294252A60010E17F /* proRawImage.dng */; };
3526
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
3627
78CF8D862BC5E7070051231B /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = 78CF8D852BC5E7070051231B /* OCMock */; };
3728
86430DF9272D71E9002D9D6C /* gifImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 9FC8F0E8229FA49E00C8D58F /* gifImage.gif */; };
@@ -44,9 +35,20 @@
4435
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
4536
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
4637
9FC8F0E9229FA49E00C8D58F /* gifImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 9FC8F0E8229FA49E00C8D58F /* gifImage.gif */; };
47-
9FC8F0EC229FA68500C8D58F /* gifImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 9FC8F0E8229FA49E00C8D58F /* gifImage.gif */; };
4838
BE6173D826A958B800D0974D /* ImagePickerFromLimitedGalleryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6173D726A958B800D0974D /* ImagePickerFromLimitedGalleryUITests.m */; };
4939
F4F7A436CCA4BF276270A3AE /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EC32F6993F4529982D9519F1 /* libPods-Runner.a */; };
40+
F706BF732E433163001263B9 /* jpgImageTall.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F706BF722E433163001263B9 /* jpgImageTall.jpg */; };
41+
F706BF762E4331C4001263B9 /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
42+
F706BF772E4331C4001263B9 /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
43+
F706BF782E4331C4001263B9 /* icnsImage.icns in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FB294157BB0010E17F /* icnsImage.icns */; };
44+
F706BF792E4331C4001263B9 /* icoImage.ico in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E9294137960010E17F /* icoImage.ico */; };
45+
F706BF7A2E4331C4001263B9 /* jpgImageTall.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F706BF722E433163001263B9 /* jpgImageTall.jpg */; };
46+
F706BF7B2E4331C4001263B9 /* proRawImage.dng in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5FE294252A60010E17F /* proRawImage.dng */; };
47+
F706BF7C2E4331C4001263B9 /* heicImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E62941374F0010E17F /* heicImage.heic */; };
48+
F706BF7D2E4331C4001263B9 /* tiffImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5EC294137AB0010E17F /* tiffImage.tiff */; };
49+
F706BF7E2E4331C4001263B9 /* jpgImageWithRightOrientation.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 782C2B44299ECE33008DC703 /* jpgImageWithRightOrientation.jpg */; };
50+
F706BF7F2E4331C4001263B9 /* webpImage.webp in Resources */ = {isa = PBXBuildFile; fileRef = 86E9A88F272747B90017E6E0 /* webpImage.webp */; };
51+
F706BF802E4331C4001263B9 /* bmpImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 7865C5E02941326F0010E17F /* bmpImage.bmp */; };
5052
/* End PBXBuildFile section */
5153

5254
/* Begin PBXContainerItemProxy section */
@@ -122,6 +124,7 @@
122124
BE6173D726A958B800D0974D /* ImagePickerFromLimitedGalleryUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagePickerFromLimitedGalleryUITests.m; sourceTree = "<group>"; };
123125
DC6FCAAD4E7580C9B3C2E21D /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
124126
EC32F6993F4529982D9519F1 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
127+
F706BF722E433163001263B9 /* jpgImageTall.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = jpgImageTall.jpg; sourceTree = "<group>"; };
125128
F78AF3172342D9D7008449C7 /* ImagePickerTestImages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagePickerTestImages.h; sourceTree = "<group>"; };
126129
F78AF3182342D9D7008449C7 /* ImagePickerTestImages.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagePickerTestImages.m; sourceTree = "<group>"; };
127130
/* End PBXFileReference section */
@@ -177,6 +180,7 @@
177180
86E9A88F272747B90017E6E0 /* webpImage.webp */,
178181
9FC8F0E8229FA49E00C8D58F /* gifImage.gif */,
179182
680049362280F2B8006DD6AB /* jpgImage.jpg */,
183+
F706BF722E433163001263B9 /* jpgImageTall.jpg */,
180184
680049352280F2B8006DD6AB /* pngImage.png */,
181185
7865C5E02941326F0010E17F /* bmpImage.bmp */,
182186
7865C5E62941374F0010E17F /* heicImage.heic */,
@@ -407,6 +411,7 @@
407411
86430DF9272D71E9002D9D6C /* gifImage.gif in Resources */,
408412
7865C5FF294252A60010E17F /* proRawImage.dng in Resources */,
409413
7865C5EA294137960010E17F /* icoImage.ico in Resources */,
414+
F706BF732E433163001263B9 /* jpgImageTall.jpg in Resources */,
410415
7865C5E72941374F0010E17F /* heicImage.heic in Resources */,
411416
86E9A894272754A30017E6E0 /* webpImage.webp in Resources */,
412417
86E9A895272769130017E6E0 /* pngImage.png in Resources */,
@@ -421,16 +426,6 @@
421426
isa = PBXResourcesBuildPhase;
422427
buildActionMask = 2147483647;
423428
files = (
424-
9FC8F0EC229FA68500C8D58F /* gifImage.gif in Resources */,
425-
7865C5EE294137AB0010E17F /* tiffImage.tiff in Resources */,
426-
782C2B46299ECE33008DC703 /* jpgImageWithRightOrientation.jpg in Resources */,
427-
7865C5E82941374F0010E17F /* heicImage.heic in Resources */,
428-
7865C5FD294157BC0010E17F /* icnsImage.icns in Resources */,
429-
680049382280F2B9006DD6AB /* pngImage.png in Resources */,
430-
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */,
431-
7865C5EB294137960010E17F /* icoImage.ico in Resources */,
432-
7865C5E22941326F0010E17F /* bmpImage.bmp in Resources */,
433-
7865C600294252A60010E17F /* proRawImage.dng in Resources */,
434429
);
435430
runOnlyForDeploymentPostprocessing = 0;
436431
};
@@ -439,6 +434,17 @@
439434
buildActionMask = 2147483647;
440435
files = (
441436
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
437+
F706BF762E4331C4001263B9 /* pngImage.png in Resources */,
438+
F706BF772E4331C4001263B9 /* jpgImage.jpg in Resources */,
439+
F706BF782E4331C4001263B9 /* icnsImage.icns in Resources */,
440+
F706BF792E4331C4001263B9 /* icoImage.ico in Resources */,
441+
F706BF7A2E4331C4001263B9 /* jpgImageTall.jpg in Resources */,
442+
F706BF7B2E4331C4001263B9 /* proRawImage.dng in Resources */,
443+
F706BF7C2E4331C4001263B9 /* heicImage.heic in Resources */,
444+
F706BF7D2E4331C4001263B9 /* tiffImage.tiff in Resources */,
445+
F706BF7E2E4331C4001263B9 /* jpgImageWithRightOrientation.jpg in Resources */,
446+
F706BF7F2E4331C4001263B9 /* webpImage.webp in Resources */,
447+
F706BF802E4331C4001263B9 /* bmpImage.bmp in Resources */,
442448
9FC8F0E9229FA49E00C8D58F /* gifImage.gif in Resources */,
443449
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
444450
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,

packages/image_picker/image_picker_ios/example/ios/Runner/AppDelegate.m

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,43 @@
55
#include "AppDelegate.h"
66
#include "GeneratedPluginRegistrant.h"
77

8+
@import Photos;
9+
@import os.log;
10+
811
@implementation AppDelegate
912

1013
- (BOOL)application:(UIApplication *)application
1114
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
1215
[GeneratedPluginRegistrant registerWithRegistry:self];
16+
if (@available(iOS 14, *)) {
17+
// Seed the photo library with at least one image for tests to operate on.
18+
NSString *photoAddedKey = @"PhotoAdded";
19+
BOOL photoAdded = [NSUserDefaults.standardUserDefaults boolForKey:photoAddedKey];
20+
if (!photoAdded) {
21+
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
22+
__block NSError *saveError = nil;
23+
[PHPhotoLibrary
24+
requestAuthorizationForAccessLevel:PHAccessLevelAddOnly
25+
handler:^(PHAuthorizationStatus status) {
26+
if ([PHPhotoLibrary.sharedPhotoLibrary
27+
performChangesAndWait:^{
28+
NSURL *jpgImageTall =
29+
[bundle URLForResource:@"jpgImageTall"
30+
withExtension:@"jpg"];
31+
[PHAssetChangeRequest
32+
creationRequestForAssetFromImageAtFileURL:
33+
jpgImageTall];
34+
}
35+
error:&saveError]) {
36+
[NSUserDefaults.standardUserDefaults
37+
setBool:YES
38+
forKey:photoAddedKey];
39+
} else {
40+
os_log_error(OS_LOG_DEFAULT, "%@", saveError);
41+
}
42+
}];
43+
}
44+
}
1345
return [super application:application didFinishLaunchingWithOptions:launchOptions];
1446
}
1547

packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromGalleryUITests.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,14 @@ - (void)launchPickerAndPickWithMaxWidth:(NSNumber *)maxWidth
220220
os_log_error(OS_LOG_DEFAULT, "%@", self.app.debugDescription);
221221
XCTFail(@"Failed due to not able to find an image with %@ seconds", @(kElementWaitingTime));
222222
}
223-
[aImage tap];
223+
if (aImage.isHittable) {
224+
[aImage tap];
225+
} else {
226+
// Known issue where tappable elements are not hittable. Tap it anyway.
227+
// See https://github.com/flutter/plugins/pull/6783 for a similar case.
228+
XCUICoordinate *coordinate = [aImage coordinateWithNormalizedOffset:CGVectorMake(0, 0)];
229+
[coordinate tap];
230+
}
224231

225232
// Find the picked image.
226233
XCUIElement *pickedImage = self.app.images[@"image_picker_example_picked_image"].firstMatch;

packages/image_picker/image_picker_ios/example/ios/RunnerUITests/ImagePickerFromLimitedGalleryUITests.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,14 @@ - (void)testSelectingFromGallery API_AVAILABLE(ios(14)) {
115115
@(kLimitedElementWaitingTime));
116116
}
117117

118-
[aImage tap];
118+
if (aImage.isHittable) {
119+
[aImage tap];
120+
} else {
121+
// Known issue where tappable elements are not hittable. Tap it anyway.
122+
// See https://github.com/flutter/plugins/pull/6783 for a similar case.
123+
XCUICoordinate *coordinate = [aImage coordinateWithNormalizedOffset:CGVectorMake(0, 0)];
124+
[coordinate tap];
125+
}
119126

120127
// Find the picked image.
121128
XCUIElement *pickedImage = self.app.images[@"image_picker_example_picked_image"].firstMatch;

0 commit comments

Comments
 (0)