If, like me, you've been banging your head against the brick wall that is the iOS ALAssetsLibrary writeImageToSavedPhotosAlbum:metadata:completionBlock: in an attempt to get it to save GPS data, then enjoy this soothing compress:
CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, metaDict);
NSDictionary *gpsDict = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:self.currentLocation.coordinate.latitude], kCGImagePropertyGPSLatitude,
@"N", kCGImagePropertyGPSLatitudeRef,
[NSNumber numberWithFloat:self.currentLocation.coordinate.longitude], kCGImagePropertyGPSLongitude,
@"E", kCGImagePropertyGPSLongitudeRef,
@"04:30:51.71", kCGImagePropertyGPSTimeStamp,
nil];
CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, gpsDict);
// Get the image
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
// Get the assets library
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:mutable completionBlock:captureComplete];
This should live in the completionHandler of the captureStillImageAsynchronouslyFromConnection method of your AVCaptureConnection object. self.currentLocation is just a CLLocation and GPSTimestamp (A UTC timestamp) and Lat/Lng Ref are hardcoded here for simplicity's sake. And who dislikes simplicity?