Skip to content

Commit ea2b7a6

Browse files
authored
fix: route iOS write tags to correct EXIF dictionaries (#11) (#23)
1 parent 77afa09 commit ea2b7a6

3 files changed

Lines changed: 54 additions & 41 deletions

File tree

example/src/App.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ export default function App() {
4444
GPSLongitude: lng,
4545
GPSTimeStamp: '10:10:10',
4646
GPSDateStamp: '2024:10:10',
47+
GPSDOP: 5.0,
48+
GPSImgDirection: 180.5,
49+
GPSImgDirectionRef: 'T',
4750
UserComment: 'Exif updated via @lodev09/react-native-exify',
51+
Make: 'Exify',
52+
Model: 'ExifyCamera',
53+
Software: 'react-native-exify',
54+
DateTime: '2024:10:10 10:10:10',
4855
};
4956

5057
console.log('writeExif:', json(tags));

ios/Exify.mm

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
#import "Exify.h"
22

3+
static NSSet *tiffKeys;
4+
5+
__attribute__((constructor)) static void initTiffKeys(void) {
6+
tiffKeys = [NSSet setWithObjects:@"Make", @"Model", @"Software", @"DateTime",
7+
@"Artist", @"Copyright", @"ImageDescription",
8+
@"Orientation", @"XResolution",
9+
@"YResolution", @"ResolutionUnit",
10+
@"Compression", @"PhotometricInterpretation",
11+
@"TransferFunction", @"WhitePoint",
12+
@"PrimaryChromaticities", @"HostComputer",
13+
nil];
14+
}
15+
316
#pragma mark - Helpers
417

518
static PHAsset *getAssetById(NSString *assetId) {
@@ -95,58 +108,50 @@ static void addTagEntries(CFStringRef dictionary, NSDictionary *metadata,
95108
props]
96109
: [NSMutableDictionary new];
97110

98-
// Merge into Exif dict (filter out GPS-prefixed keys)
111+
// Route tags into the correct sub-dictionaries
99112
NSMutableDictionary *exifDict = [NSMutableDictionary
100113
dictionaryWithDictionary:metadata[(__bridge NSString *)
101114
kCGImagePropertyExifDictionary]
102115
?: @{}];
103-
for (NSString *key in tags) {
104-
if (![key hasPrefix:@"GPS"]) {
105-
exifDict[key] = tags[key];
106-
}
107-
}
108-
metadata[(__bridge NSString *)kCGImagePropertyExifDictionary] = exifDict;
109-
110-
// Handle GPS tags
116+
NSMutableDictionary *tiffDict = [NSMutableDictionary
117+
dictionaryWithDictionary:metadata[(__bridge NSString *)
118+
kCGImagePropertyTIFFDictionary]
119+
?: @{}];
111120
NSMutableDictionary *gpsDict = [NSMutableDictionary
112121
dictionaryWithDictionary:metadata[(__bridge NSString *)
113122
kCGImagePropertyGPSDictionary]
114123
?: @{}];
115124

116-
NSNumber *latitude = tags[@"GPSLatitude"];
117-
if (latitude) {
118-
double lat = latitude.doubleValue;
119-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLatitude] = @(fabs(lat));
120-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLatitudeRef] =
121-
lat >= 0 ? @"N" : @"S";
122-
}
123-
124-
NSNumber *longitude = tags[@"GPSLongitude"];
125-
if (longitude) {
126-
double lng = longitude.doubleValue;
127-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLongitude] = @(fabs(lng));
128-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLongitudeRef] =
129-
lng >= 0 ? @"E" : @"W";
130-
}
131-
132-
NSNumber *altitude = tags[@"GPSAltitude"];
133-
if (altitude) {
134-
double alt = altitude.doubleValue;
135-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSAltitude] = @(fabs(alt));
136-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSAltitudeRef] =
137-
@(alt >= 0 ? 0 : 1);
138-
}
139-
140-
NSString *gpsDate = tags[@"GPSDateStamp"];
141-
if (gpsDate) {
142-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSDateStamp] = gpsDate;
143-
}
144-
145-
NSString *gpsTime = tags[@"GPSTimeStamp"];
146-
if (gpsTime) {
147-
gpsDict[(__bridge NSString *)kCGImagePropertyGPSTimeStamp] = gpsTime;
125+
for (NSString *key in tags) {
126+
id value = tags[key];
127+
128+
if ([key isEqualToString:@"GPSLatitude"]) {
129+
double lat = [value doubleValue];
130+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLatitude] = @(fabs(lat));
131+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLatitudeRef] =
132+
lat >= 0 ? @"N" : @"S";
133+
} else if ([key isEqualToString:@"GPSLongitude"]) {
134+
double lng = [value doubleValue];
135+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLongitude] =
136+
@(fabs(lng));
137+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSLongitudeRef] =
138+
lng >= 0 ? @"E" : @"W";
139+
} else if ([key isEqualToString:@"GPSAltitude"]) {
140+
double alt = [value doubleValue];
141+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSAltitude] = @(fabs(alt));
142+
gpsDict[(__bridge NSString *)kCGImagePropertyGPSAltitudeRef] =
143+
@(alt >= 0 ? 0 : 1);
144+
} else if ([key hasPrefix:@"GPS"]) {
145+
gpsDict[[key substringFromIndex:3]] = value;
146+
} else if ([tiffKeys containsObject:key]) {
147+
tiffDict[key] = value;
148+
} else {
149+
exifDict[key] = value;
150+
}
148151
}
149152

153+
metadata[(__bridge NSString *)kCGImagePropertyExifDictionary] = exifDict;
154+
metadata[(__bridge NSString *)kCGImagePropertyTIFFDictionary] = tiffDict;
150155
metadata[(__bridge NSString *)kCGImagePropertyGPSDictionary] = gpsDict;
151156
metadata[(__bridge NSString *)kCGImageDestinationLossyCompressionQuality] =
152157
@(1);

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export interface ExifTags {
139139
SubjectDistanceRange?: number;
140140
XResolution?: number;
141141
Software?: string;
142+
HostComputer?: string;
142143
[key: string]: unknown;
143144
}
144145

0 commit comments

Comments
 (0)