Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone Get UIImagePickerController Lat/Lng

I'm using the UIImagePickerController to take a photo and then upload the photo to a WCF Service. Along with the image, I also need to send to the latitude and longitude of the photo.

How can I get hold of this information from the photo taken?

I've searched online but can't seem to find a good source of info. I've seen about the EXIF data that is passed through the UIImagePickerControllerMediaMetadata key as part of the didFinishPickingMediaWithInfo delegate method. However, when I print out the contents to the log, there's no location information.

Am I missing something, do I need to turn on location services prior to taking the photo? Or is there another way to get the information?

Many thanks.

like image 367
Dan Ellis Avatar asked May 30 '11 14:05

Dan Ellis


2 Answers

I've been figuring this out for a couple of days, and finally got a solution. As already suggested, you can use ALAssetsLibrary.

The image picker will give you a dictionary, which contains an url that points to the asset.

The ALAssetsLibrary's assetForURL: resultBlock: failureBlock: method uses blocks. You can read more about them from example here. So this is how we handle the info given by the picker:

- (void)imagePickerController:(UIImagePickerController *)picker
            didFinishPickingMediaWithInfo:(NSDictionary *)info
{

    if ([picker sourceType] == UIImagePickerControllerSourceTypePhotoLibrary) {
        // We'll store the info to use in another function later
        self.imageInfo = info;

        // Get the asset url
        NSURL *url = [info objectForKey:@"UIImagePickerControllerReferenceURL"];

        // We need to use blocks. This block will handle the ALAsset that's returned: 
        ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
        {
            // Get the location property from the asset  
            CLLocation *location = [myasset valueForProperty:ALAssetPropertyLocation];
            // I found that the easiest way is to send the location to another method
            [self handleImageLocation:location];
        };
        // This block will handle errors:
        ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
        {
            NSLog(@"Can not get asset - %@",[myerror localizedDescription]);
            // Do something to handle the error
        };


        // Use the url to get the asset from ALAssetsLibrary,
        // the blocks that we just created will handle results
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:url 
                       resultBlock:resultblock
                      failureBlock:failureblock];

    }
    [picker dismissModalViewControllerAnimated:YES];
    [picker release];
}

And next the method that handles the image and location data:

- handleImageLocation:(CLLocation *)location 
{
    UIImage *image = [self.imageInfo objectForKey:UIImagePickerControllerOriginalImage];
    // Do something with the image and location data...
}

And of course you can also get other information about the image with this method by using keys:

ALAssetPropertyType
ALAssetPropertyLocation
ALAssetPropertyDuration
ALAssetPropertyOrientation
ALAssetPropertyDate
ALAssetPropertyRepresentations
ALAssetPropertyURLs
like image 111
lari Avatar answered Sep 27 '22 20:09

lari


New since iOS 8

It was complicated with ALAssetLibrary, which is now deprecated, use Photos.Framework instead.

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    if let assertURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
        let fetchResult = PHAsset.fetchAssetsWithALAssetURLs([assertURL], options: nil)
        if let asset = fetchResult.firstObject as? PHAsset
        {
            print(asset.location)
        }
    }
}

Quick and easy :)

like image 30
Yuchen Avatar answered Sep 27 '22 22:09

Yuchen