Skip to content

Commit

Permalink
Merge pull request #55011 from software-mansion-labs/@wolewicki/fix-i…
Browse files Browse the repository at this point in the history
…mage-gallery-picker

fix: dispatch callback after dismissing modal
(cherry picked from commit a6ccbd0)

(CP triggered by mountiny)
  • Loading branch information
marcochavezf authored and OSBotify committed Jan 9, 2025
1 parent d7dc5f4 commit 1a32aa8
Showing 1 changed file with 150 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
diff --git a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
index 93e99be..0ef2a8a 100644
--- a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
+++ b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
@@ -506,81 +506,85 @@ @implementation ImagePickerManager (PHPickerViewControllerDelegate)

- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14))
{
- [picker dismissViewControllerAnimated:YES completion:nil];
-
- if (photoSelected == YES) {
- return;
- }
- photoSelected = YES;
-
- if (results.count == 0) {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.callback(@[@{@"didCancel": @YES}]);
- });
- return;
- }
+ dispatch_block_t dismissCompletionBlock = ^{

- dispatch_group_t completionGroup = dispatch_group_create();
- NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:results.count];
- for (int i = 0; i < results.count; i++) {
- [assets addObject:(NSDictionary *)[NSNull null]];
- }
+ if (photoSelected == YES) {
+ return;
+ }
+ photoSelected = YES;

- [results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger index, BOOL *stop) {
- PHAsset *asset = nil;
- NSItemProvider *provider = result.itemProvider;
+ if (results.count == 0) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ self.callback(@[@{@"didCancel": @YES}]);
+ });
+ return;
+ }

- // If include extra, we fetch the PHAsset, this required library permissions
- if([self.options[@"includeExtra"] boolValue] && result.assetIdentifier != nil) {
- PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[result.assetIdentifier] options:nil];
- asset = fetchResult.firstObject;
+ dispatch_group_t completionGroup = dispatch_group_create();
+ NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:results.count];
+ for (int i = 0; i < results.count; i++) {
+ [assets addObject:(NSDictionary *)[NSNull null]];
}

- dispatch_group_enter(completionGroup);
+ [results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger index, BOOL *stop) {
+ PHAsset *asset = nil;
+ NSItemProvider *provider = result.itemProvider;

- if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
- NSString *identifier = provider.registeredTypeIdentifiers.firstObject;
- // Matches both com.apple.live-photo-bundle and com.apple.private.live-photo-bundle
- if ([identifier containsString:@"live-photo-bundle"]) {
- // Handle live photos
- identifier = @"public.jpeg";
+ // If include extra, we fetch the PHAsset, this required library permissions
+ if([self.options[@"includeExtra"] boolValue] && result.assetIdentifier != nil) {
+ PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[result.assetIdentifier] options:nil];
+ asset = fetchResult.firstObject;
}

- [provider loadFileRepresentationForTypeIdentifier:identifier completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
- NSData *data = [[NSData alloc] initWithContentsOfURL:url];
- UIImage *image = [[UIImage alloc] initWithData:data];
+ dispatch_group_enter(completionGroup);

- assets[index] = [self mapImageToAsset:image data:data phAsset:asset];
- dispatch_group_leave(completionGroup);
- }];
- } else if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie]) {
- [provider loadFileRepresentationForTypeIdentifier:(NSString *)kUTTypeMovie completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
- NSDictionary *mappedAsset = [self mapVideoToAsset:url phAsset:asset error:nil];
- if (nil != mappedAsset) {
- assets[index] = mappedAsset;
+ if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
+ NSString *identifier = provider.registeredTypeIdentifiers.firstObject;
+ // Matches both com.apple.live-photo-bundle and com.apple.private.live-photo-bundle
+ if ([identifier containsString:@"live-photo-bundle"]) {
+ // Handle live photos
+ identifier = @"public.jpeg";
}
+
+ [provider loadFileRepresentationForTypeIdentifier:identifier completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
+ NSData *data = [[NSData alloc] initWithContentsOfURL:url];
+ UIImage *image = [[UIImage alloc] initWithData:data];
+
+ assets[index] = [self mapImageToAsset:image data:data phAsset:asset];
+ dispatch_group_leave(completionGroup);
+ }];
+ } else if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie]) {
+ [provider loadFileRepresentationForTypeIdentifier:(NSString *)kUTTypeMovie completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
+ NSDictionary *mappedAsset = [self mapVideoToAsset:url phAsset:asset error:nil];
+ if (nil != mappedAsset) {
+ assets[index] = mappedAsset;
+ }
+ dispatch_group_leave(completionGroup);
+ }];
+ } else {
+ // The provider didn't have an item matching photo or video (fails on M1 Mac Simulator)
dispatch_group_leave(completionGroup);
- }];
- } else {
- // The provider didn't have an item matching photo or video (fails on M1 Mac Simulator)
- dispatch_group_leave(completionGroup);
- }
- }];
+ }
+ }];

- dispatch_group_notify(completionGroup, dispatch_get_main_queue(), ^{
- // mapVideoToAsset can fail and return nil, leaving asset NSNull.
- for (NSDictionary *asset in assets) {
- if ([asset isEqual:[NSNull null]]) {
- self.callback(@[@{@"errorCode": errOthers}]);
- return;
+ dispatch_group_notify(completionGroup, dispatch_get_main_queue(), ^{
+ // mapVideoToAsset can fail and return nil, leaving asset NSNull.
+ for (NSDictionary *asset in assets) {
+ if ([asset isEqual:[NSNull null]]) {
+ self.callback(@[@{@"errorCode": errOthers}]);
+ return;
+ }
}
- }

- NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
- [response setObject:assets forKey:@"assets"];
+ NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
+ [response setObject:assets forKey:@"assets"];
+
+ self.callback(@[response]);
+ });
+ };
+
+ [picker dismissViewControllerAnimated:YES completion:dismissCompletionBlock];

- self.callback(@[response]);
- });
}

@end

0 comments on commit 1a32aa8

Please sign in to comment.