@@ -219,14 +219,30 @@ - (void)launchImagePicker:(RNImagePickerTarget)target
219
219
}
220
220
}
221
221
222
+ - (NSString * _Nullable)originalFilenameForAsset : (PHAsset * _Nullable)asset assetType : (PHAssetResourceType)type {
223
+ if (!asset) { return nil ; }
224
+
225
+ PHAssetResource *originalResource;
226
+ // Get the underlying resources for the PHAsset (PhotoKit)
227
+ NSArray <PHAssetResource *> *pickedAssetResources = [PHAssetResource assetResourcesForAsset: asset];
228
+
229
+ // Find the original resource (underlying image) for the asset, which has the desired filename
230
+ for (PHAssetResource *resource in pickedAssetResources) {
231
+ if (resource.type == type) {
232
+ originalResource = resource;
233
+ }
234
+ }
235
+
236
+ return originalResource.originalFilename ;
237
+ }
238
+
222
239
- (void )imagePickerController : (UIImagePickerController *)picker didFinishPickingMediaWithInfo : (NSDictionary <NSString *,id> *)info
223
240
{
224
241
dispatch_block_t dismissCompletionBlock = ^{
225
242
226
243
NSURL *imageURL = [info valueForKey: UIImagePickerControllerReferenceURL];
227
244
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
228
245
229
-
230
246
NSString *fileName;
231
247
if ([mediaType isEqualToString: (NSString *)kUTTypeImage ]) {
232
248
NSString *tempFileName = [[NSUUID UUID ] UUIDString ];
@@ -284,6 +300,19 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking
284
300
image = [info objectForKey: UIImagePickerControllerOriginalImage];
285
301
}
286
302
303
+ if (imageURL) {
304
+ PHAsset *pickedAsset = [PHAsset fetchAssetsWithALAssetURLs: @[imageURL] options: nil ].lastObject ;
305
+ NSString *originalFilename = [self originalFilenameForAsset: pickedAsset assetType: PHAssetResourceTypePhoto];
306
+ self.response [@" fileName" ] = originalFilename ?: [NSNull null ];
307
+ if (pickedAsset.location ) {
308
+ self.response [@" latitude" ] = @(pickedAsset.location .coordinate .latitude );
309
+ self.response [@" longitude" ] = @(pickedAsset.location .coordinate .longitude );
310
+ }
311
+ if (pickedAsset.creationDate ) {
312
+ self.response [@" timestamp" ] = [[ImagePickerManager ISO8601DateFormatter ] stringFromDate: pickedAsset.creationDate];
313
+ }
314
+ }
315
+
287
316
// GIFs break when resized, so we handle them differently
288
317
if (imageURL && [[imageURL absoluteString ] rangeOfString: @" ext=GIF" ].location != NSNotFound ) {
289
318
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc ] init ];
@@ -374,10 +403,27 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking
374
403
375
404
NSDictionary *storageOptions = [self .options objectForKey: @" storageOptions" ];
376
405
if (storageOptions && [[storageOptions objectForKey: @" cameraRoll" ] boolValue ] == YES && self.picker .sourceType == UIImagePickerControllerSourceTypeCamera) {
406
+ ALAssetsLibrary *library = [[ALAssetsLibrary alloc ] init ];
377
407
if ([[storageOptions objectForKey: @" waitUntilSaved" ] boolValue ]) {
378
- UIImageWriteToSavedPhotosAlbum (image, self, @selector (savedImage : hasBeenSavedInPhotoAlbumWithError : usingContextInfo :), nil );
408
+ [library writeImageToSavedPhotosAlbum: image.CGImage metadata: [info valueForKey: UIImagePickerControllerMediaMetadata] completionBlock: ^(NSURL *assetURL, NSError *error) {
409
+ if (error) {
410
+ NSLog (@" Error while saving picture into photo album" );
411
+ } else {
412
+ // when the image has been saved in the photo album
413
+ if (assetURL) {
414
+ PHAsset *capturedAsset = [PHAsset fetchAssetsWithALAssetURLs: @[assetURL] options: nil ].lastObject ;
415
+ NSString *originalFilename = [self originalFilenameForAsset: capturedAsset assetType: PHAssetResourceTypePhoto];
416
+ self.response [@" fileName" ] = originalFilename ?: [NSNull null ];
417
+ // This implementation will never have a location for the captured image, it needs to be added manually with CoreLocation code here.
418
+ if (capturedAsset.creationDate ) {
419
+ self.response [@" timestamp" ] = [[ImagePickerManager ISO8601DateFormatter ] stringFromDate: capturedAsset.creationDate];
420
+ }
421
+ }
422
+ self.callback (@[self .response]);
423
+ }
424
+ }];
379
425
} else {
380
- UIImageWriteToSavedPhotosAlbum ( image, nil , nil , nil ) ;
426
+ [library writeImageToSavedPhotosAlbum: image.CGImage metadata: [info valueForKey: UIImagePickerControllerMediaMetadata] completionBlock: nil ] ;
381
427
}
382
428
}
383
429
}
@@ -386,6 +432,19 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking
386
432
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
387
433
NSURL *videoDestinationURL = [NSURL fileURLWithPath: path];
388
434
435
+ if (videoRefURL) {
436
+ PHAsset *pickedAsset = [PHAsset fetchAssetsWithALAssetURLs: @[videoRefURL] options: nil ].lastObject ;
437
+ NSString *originalFilename = [self originalFilenameForAsset: pickedAsset assetType: PHAssetResourceTypeVideo];
438
+ self.response [@" fileName" ] = originalFilename ?: [NSNull null ];
439
+ if (pickedAsset.location ) {
440
+ self.response [@" latitude" ] = @(pickedAsset.location .coordinate .latitude );
441
+ self.response [@" longitude" ] = @(pickedAsset.location .coordinate .longitude );
442
+ }
443
+ if (pickedAsset.creationDate ) {
444
+ self.response [@" timestamp" ] = [[ImagePickerManager ISO8601DateFormatter ] stringFromDate: pickedAsset.creationDate];
445
+ }
446
+ }
447
+
389
448
if ([videoURL.URLByResolvingSymlinksInPath.path isEqualToString: videoDestinationURL.URLByResolvingSymlinksInPath.path] == NO ) {
390
449
NSFileManager *fileManager = [NSFileManager defaultManager ];
391
450
@@ -417,6 +476,16 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking
417
476
} else {
418
477
NSLog (@" Save video succeed." );
419
478
if ([[storageOptions objectForKey: @" waitUntilSaved" ] boolValue ]) {
479
+ if (assetURL) {
480
+ PHAsset *capturedAsset = [PHAsset fetchAssetsWithALAssetURLs: @[assetURL] options: nil ].lastObject ;
481
+ NSString *originalFilename = [self originalFilenameForAsset: capturedAsset assetType: PHAssetResourceTypeVideo];
482
+ self.response [@" fileName" ] = originalFilename ?: [NSNull null ];
483
+ // This implementation will never have a location for the captured image, it needs to be added manually with CoreLocation code here.
484
+ if (capturedAsset.creationDate ) {
485
+ self.response [@" timestamp" ] = [[ImagePickerManager ISO8601DateFormatter ] stringFromDate: capturedAsset.creationDate];
486
+ }
487
+ }
488
+
420
489
self.callback (@[self .response]);
421
490
}
422
491
}
@@ -458,16 +527,6 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
458
527
});
459
528
}
460
529
461
- - (void )savedImage : (UIImage *)image hasBeenSavedInPhotoAlbumWithError : (NSError *)error usingContextInfo : (void *)ctxInfo
462
- {
463
- if (error) {
464
- NSLog (@" Error while saving picture into photo album" );
465
- } else {
466
- // when the image has been saved in the photo album
467
- self.callback (@[self .response]);
468
- }
469
- }
470
-
471
530
#pragma mark - Helpers
472
531
473
532
- (void )checkCameraPermissions : (void (^)(BOOL granted))callback
@@ -630,4 +689,19 @@ - (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
630
689
}
631
690
}
632
691
692
+ #pragma mark - Class Methods
693
+
694
+ + (NSDateFormatter * _Nonnull)ISO8601DateFormatter {
695
+ static NSDateFormatter *ISO8601DateFormatter;
696
+ static dispatch_once_t onceToken;
697
+ dispatch_once (&onceToken, ^{
698
+ ISO8601DateFormatter = [[NSDateFormatter alloc ] init ];
699
+ NSLocale *enUSPOSIXLocale = [NSLocale localeWithLocaleIdentifier: @" en_US_POSIX" ];
700
+ ISO8601DateFormatter.locale = enUSPOSIXLocale;
701
+ ISO8601DateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @" GMT" ];
702
+ ISO8601DateFormatter.dateFormat = @" yyyy-MM-dd'T'HH:mm:ssZZZZZ" ;
703
+ });
704
+ return ISO8601DateFormatter;
705
+ }
706
+
633
707
@end
0 commit comments