Skip to content

Commit ba37e37

Browse files
committed
fix: dispatch callback after dismissing modal
1 parent 5fb81d6 commit ba37e37

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
diff --git a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
2+
index 93e99be..0ef2a8a 100644
3+
--- a/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
4+
+++ b/node_modules/react-native-image-picker/ios/ImagePickerManager.mm
5+
@@ -506,81 +506,85 @@ @implementation ImagePickerManager (PHPickerViewControllerDelegate)
6+
7+
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14))
8+
{
9+
- [picker dismissViewControllerAnimated:YES completion:nil];
10+
-
11+
- if (photoSelected == YES) {
12+
- return;
13+
- }
14+
- photoSelected = YES;
15+
-
16+
- if (results.count == 0) {
17+
- dispatch_async(dispatch_get_main_queue(), ^{
18+
- self.callback(@[@{@"didCancel": @YES}]);
19+
- });
20+
- return;
21+
- }
22+
+ dispatch_block_t dismissCompletionBlock = ^{
23+
24+
- dispatch_group_t completionGroup = dispatch_group_create();
25+
- NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:results.count];
26+
- for (int i = 0; i < results.count; i++) {
27+
- [assets addObject:(NSDictionary *)[NSNull null]];
28+
- }
29+
+ if (photoSelected == YES) {
30+
+ return;
31+
+ }
32+
+ photoSelected = YES;
33+
34+
- [results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger index, BOOL *stop) {
35+
- PHAsset *asset = nil;
36+
- NSItemProvider *provider = result.itemProvider;
37+
+ if (results.count == 0) {
38+
+ dispatch_async(dispatch_get_main_queue(), ^{
39+
+ self.callback(@[@{@"didCancel": @YES}]);
40+
+ });
41+
+ return;
42+
+ }
43+
44+
- // If include extra, we fetch the PHAsset, this required library permissions
45+
- if([self.options[@"includeExtra"] boolValue] && result.assetIdentifier != nil) {
46+
- PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[result.assetIdentifier] options:nil];
47+
- asset = fetchResult.firstObject;
48+
+ dispatch_group_t completionGroup = dispatch_group_create();
49+
+ NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:results.count];
50+
+ for (int i = 0; i < results.count; i++) {
51+
+ [assets addObject:(NSDictionary *)[NSNull null]];
52+
}
53+
54+
- dispatch_group_enter(completionGroup);
55+
+ [results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger index, BOOL *stop) {
56+
+ PHAsset *asset = nil;
57+
+ NSItemProvider *provider = result.itemProvider;
58+
59+
- if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
60+
- NSString *identifier = provider.registeredTypeIdentifiers.firstObject;
61+
- // Matches both com.apple.live-photo-bundle and com.apple.private.live-photo-bundle
62+
- if ([identifier containsString:@"live-photo-bundle"]) {
63+
- // Handle live photos
64+
- identifier = @"public.jpeg";
65+
+ // If include extra, we fetch the PHAsset, this required library permissions
66+
+ if([self.options[@"includeExtra"] boolValue] && result.assetIdentifier != nil) {
67+
+ PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[result.assetIdentifier] options:nil];
68+
+ asset = fetchResult.firstObject;
69+
}
70+
71+
- [provider loadFileRepresentationForTypeIdentifier:identifier completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
72+
- NSData *data = [[NSData alloc] initWithContentsOfURL:url];
73+
- UIImage *image = [[UIImage alloc] initWithData:data];
74+
+ dispatch_group_enter(completionGroup);
75+
76+
- assets[index] = [self mapImageToAsset:image data:data phAsset:asset];
77+
- dispatch_group_leave(completionGroup);
78+
- }];
79+
- } else if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie]) {
80+
- [provider loadFileRepresentationForTypeIdentifier:(NSString *)kUTTypeMovie completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
81+
- NSDictionary *mappedAsset = [self mapVideoToAsset:url phAsset:asset error:nil];
82+
- if (nil != mappedAsset) {
83+
- assets[index] = mappedAsset;
84+
+ if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
85+
+ NSString *identifier = provider.registeredTypeIdentifiers.firstObject;
86+
+ // Matches both com.apple.live-photo-bundle and com.apple.private.live-photo-bundle
87+
+ if ([identifier containsString:@"live-photo-bundle"]) {
88+
+ // Handle live photos
89+
+ identifier = @"public.jpeg";
90+
}
91+
+
92+
+ [provider loadFileRepresentationForTypeIdentifier:identifier completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
93+
+ NSData *data = [[NSData alloc] initWithContentsOfURL:url];
94+
+ UIImage *image = [[UIImage alloc] initWithData:data];
95+
+
96+
+ assets[index] = [self mapImageToAsset:image data:data phAsset:asset];
97+
+ dispatch_group_leave(completionGroup);
98+
+ }];
99+
+ } else if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie]) {
100+
+ [provider loadFileRepresentationForTypeIdentifier:(NSString *)kUTTypeMovie completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
101+
+ NSDictionary *mappedAsset = [self mapVideoToAsset:url phAsset:asset error:nil];
102+
+ if (nil != mappedAsset) {
103+
+ assets[index] = mappedAsset;
104+
+ }
105+
+ dispatch_group_leave(completionGroup);
106+
+ }];
107+
+ } else {
108+
+ // The provider didn't have an item matching photo or video (fails on M1 Mac Simulator)
109+
dispatch_group_leave(completionGroup);
110+
- }];
111+
- } else {
112+
- // The provider didn't have an item matching photo or video (fails on M1 Mac Simulator)
113+
- dispatch_group_leave(completionGroup);
114+
- }
115+
- }];
116+
+ }
117+
+ }];
118+
119+
- dispatch_group_notify(completionGroup, dispatch_get_main_queue(), ^{
120+
- // mapVideoToAsset can fail and return nil, leaving asset NSNull.
121+
- for (NSDictionary *asset in assets) {
122+
- if ([asset isEqual:[NSNull null]]) {
123+
- self.callback(@[@{@"errorCode": errOthers}]);
124+
- return;
125+
+ dispatch_group_notify(completionGroup, dispatch_get_main_queue(), ^{
126+
+ // mapVideoToAsset can fail and return nil, leaving asset NSNull.
127+
+ for (NSDictionary *asset in assets) {
128+
+ if ([asset isEqual:[NSNull null]]) {
129+
+ self.callback(@[@{@"errorCode": errOthers}]);
130+
+ return;
131+
+ }
132+
}
133+
- }
134+
135+
- NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
136+
- [response setObject:assets forKey:@"assets"];
137+
+ NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
138+
+ [response setObject:assets forKey:@"assets"];
139+
+
140+
+ self.callback(@[response]);
141+
+ });
142+
+ };
143+
+
144+
+ [picker dismissViewControllerAnimated:YES completion:dismissCompletionBlock];
145+
146+
- self.callback(@[response]);
147+
- });
148+
}
149+
150+
@end

0 commit comments

Comments
 (0)