Louis Ferraiolo
Louis Ferraiolo

Reputation: 429

GPSDictionary returning nil with no exif location data in metadata of uiimage

The following screenshot shows what is displayed when printing out the metadata and next to it is the exact same image which has been exported to my mac so I can view all the data from the picture (note: neither have been modified so they're exact same). enter image description here

The code which I am using to get the location data is as follows:

    UIImage *image = (UIImage*)[info objectForKey:UIImagePickerControllerOriginalImage];
    NSData *data = UIImageJPEGRepresentation( image, 0.9f );
    // EXIF DATA
    CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);

    if (mySourceRef != NULL)
    {
        NSDictionary *myMetadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef, 0, NULL);
        NSDictionary *GPSDictionary = [myMetadata objectForKey:(NSString *)kCGImagePropertyGPSDictionary];
        NSLog( @"%@", myMetadata );
        //        NSLog([GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLongitude]);
        //        NSLog([GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLatitude]);

        NSLog( @"%@", [GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLongitude]);
        NSLog( @"%@", [GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLatitude]);

    }

Edit: For clarification the application has permission to use camera roll and the camera etc. Also tested on other iPhone devices to make sure not just an iPhone X problem

Upvotes: 0

Views: 280

Answers (1)

Louis Ferraiolo
Louis Ferraiolo

Reputation: 429

Found out the issue was because I was trying to the GPS Data from a temporary picture which was basically a duplicated jpeg representation of the asset. The way around this is by getting the EXIF data from the Original asset by doing the following:

    NSURL *assetURL = (NSURL*)[info objectForKey:UIImagePickerControllerReferenceURL];
    NSData *originalData = (NSData*) [self retrieveAssetDataPhotosFramework:assetURL];    
    CGImageSourceRef mySourceRef = CGImageSourceCreateWithData((CFDataRef)originalData, NULL);

    if (mySourceRef != NULL)
    {
        NSDictionary *myMetadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(mySourceRef,0,NULL);
        NSDictionary *GPSDictionary = [myMetadata objectForKey:(NSString *)kCGImagePropertyGPSDictionary];
        NSLog( @"%@", myMetadata );
        NSLog( @"%@", [GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLongitude]);
        NSLog( @"%@", [GPSDictionary valueForKey:(NSString*)kCGImagePropertyGPSLatitude]);

    }

To get Asset URL I used a method found on here (cant find link to post now)

- (NSData *)retrieveAssetDataPhotosFramework:(NSURL *)urlMedia  {

    __block NSData *iData = nil;

    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[urlMedia] options:nil];
    PHAsset *asset = [result firstObject];

    PHImageManager *imageManager = [PHImageManager defaultManager];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    options.synchronous = YES;
    options.version = PHImageRequestOptionsVersionCurrent;

    @autoreleasepool {
        [imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
            iData = [imageData copy];
            NSLog(@"requestImageDataForAsset returned info(%@)", info);
        }];
    }

    assert(iData.length != 0);
    return iData;
}

Upvotes: 1

Related Questions