Skip to content

Commit 9417007

Browse files
author
J.T. Weaver
committed
Added new method getExifWithLocalIdentifier() that uses the photo local identifier to get the exif data. This prevents the issues some are having with the native module not resolving or rejecting the promise. This was happening becuase of permissions issues that are fixed by using the local identifier to get the image data.
1 parent 0ab4b9f commit 9417007

File tree

3 files changed

+86
-12
lines changed

3 files changed

+86
-12
lines changed

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ Exif.getExif = function (uri) {
3737
});
3838
};
3939

40+
Exif.getExifWithLocalIdentifier = function (localIdentifier) {
41+
return NativeModules.ReactNativeExif.getExifWithLocalIdentifier(localIdentifier).then(result => {
42+
if (Platform.OS === 'android') {
43+
return unifyAndroid(result);
44+
}
45+
return unifyIOS(result);
46+
});
47+
};
48+
4049
Exif.getLatLong = function (uri) {
4150
const path = uri.replace('file://', '');
4251
return NativeModules.ReactNativeExif.getLatLong(path);

ios/ReactNativeExif/ReactNativeExif.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44

55
+ (void)getExif:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
66
+ (void)getLatLong:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
7+
+ (void)getExifWithLocalIdentifier:(NSString *)localIdentifier resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
78

89
@end

ios/ReactNativeExif/ReactNativeExif.m

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <stdio.h>
2+
13
#import "ReactNativeExif.h"
24
#import <React/RCTBridge.h>
35
#import <React/RCTEventDispatcher.h>
@@ -18,13 +20,15 @@ @implementation ReactNativeExif
1820
@try {
1921

2022
if([path hasPrefix:@"assets-library"]) {
23+
printf("assets library");
2124

2225
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
2326
{
2427

2528
NSDictionary *exif = [[[myasset defaultRepresentation] metadata] sanitizedDictionaryForJSONSerialization];
2629
NSDictionary *mutableExif = [exif mutableCopy];
2730
[mutableExif setValue:myasset.defaultRepresentation.filename forKey:@"originalUri"];
31+
printf("Resolving first");
2832
resolve(mutableExif);
2933

3034
};
@@ -34,23 +38,33 @@ @implementation ReactNativeExif
3438
[assetslibrary assetForURL:url
3539
resultBlock:resultblock
3640
failureBlock:^(NSError *error) {
41+
printf("couldnt get photo");
3742
NSLog(@"error couldn't get photo");
43+
reject(@"exif.getExif", @"Failed to get exif", error);
3844
}];
3945

4046
} else {
41-
42-
NSData* pngData = [NSData dataWithContentsOfFile:path];
43-
44-
CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
45-
if (mySourceRef != NULL)
46-
{
47-
NSDictionary *exif = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef,0,NULL);
48-
CFRelease(mySourceRef);
49-
50-
NSDictionary *mutableExif = [exif mutableCopy];
51-
[mutableExif setValue:path forKey:@"originalUri"];
52-
resolve(mutableExif);
47+
PHFetchResult* assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[path] options:nil];
48+
49+
PHAsset *asset = assets.firstObject;
50+
if (asset.mediaType == PHAssetMediaTypeImage) {
51+
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
52+
53+
CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
54+
if (mySourceRef != NULL)
55+
{
56+
NSDictionary *exif = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef,0,NULL);
57+
CFRelease(mySourceRef);
58+
59+
NSDictionary *mutableExif = [exif mutableCopy];
60+
[mutableExif setValue:path forKey:@"originalUri"];
61+
resolve(mutableExif);
62+
return;
63+
}
64+
}];
5365
}
66+
67+
[NSException raise:@"Invalid local identifier" format:@"Local identifier of %@* is invalid", path];
5468
}
5569

5670
}
@@ -92,6 +106,7 @@ @implementation ReactNativeExif
92106
resultBlock:resultblock
93107
failureBlock:^(NSError *error) {
94108
NSLog(@"error couldn't get photo");
109+
reject(@"exif.getLatLong", @"Failed to get lat long", error);
95110
}];
96111

97112
} else {
@@ -107,9 +122,22 @@ @implementation ReactNativeExif
107122
if (! location) {
108123
return resolve(nil);
109124
}
125+
126+
for(NSString *key in [location allKeys]) {
127+
NSLog(@"%@ : %@",key, [location objectForKey:key]);
128+
}
110129

111130
NSNumber *latitude = [location objectForKey:@"Latitude"];
112131
NSNumber *longitude = [location objectForKey:@"Longitude"];
132+
NSString *latitudeRef = [location objectForKey:@"LatitudeRef"];
133+
NSString *longitudeRef = [location objectForKey:@"LongitudeRef"];
134+
135+
if ([@"S" isEqualToString:latitudeRef]) {
136+
latitude = @(- latitude.doubleValue);
137+
}
138+
if ([@"W" isEqualToString:longitudeRef]) {
139+
longitude = @(- longitude.doubleValue);
140+
}
113141

114142
NSMutableDictionary *latLongDict = [[NSMutableDictionary alloc] init];
115143
[latLongDict setValue:latitude forKey:@"latitude"];
@@ -127,4 +155,40 @@ @implementation ReactNativeExif
127155
}
128156
}
129157

158+
RCT_EXPORT_METHOD(getExifWithLocalIdentifier:(NSString *)localIdentifier resolver:(RCTPromiseResolveBlock)resolve
159+
rejecter:(RCTPromiseRejectBlock)reject) {
160+
161+
@try {
162+
163+
PHFetchResult* assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
164+
PHAsset *asset = assets.firstObject;
165+
if (asset.mediaType != PHAssetMediaTypeImage) {
166+
[NSException raise:@"Asset is not an image" format:@"Asset for provided local identifier %@* is not an image", localIdentifier];
167+
return;
168+
}
169+
170+
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
171+
CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
172+
173+
if (mySourceRef == NULL) {
174+
[NSException raise:@"Could not load image" format:@"The image could not be loaded"];
175+
}
176+
NSDictionary *exif = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef,0,NULL);
177+
CFRelease(mySourceRef);
178+
179+
NSDictionary *mutableExif = [exif mutableCopy];
180+
[mutableExif setValue:localIdentifier forKey:@"originalUri"];
181+
resolve(mutableExif);
182+
}];
183+
184+
}
185+
@catch (NSException *exception) {
186+
NSLog(@"%@", exception.reason);
187+
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: exception.reason};
188+
NSError *error = [NSError errorWithDomain:@"world" code:200 userInfo:userInfo];
189+
reject(@"fail", @"getExifWithLocalIdentifier", error);
190+
}
191+
192+
}
193+
130194
@end

0 commit comments

Comments
 (0)