Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ALAssetPropertyLocation not working on any iOS 4.0+ on 3gs iPhones but working perfectly on iPhone4

I've got an app with location services ENABLED (from settings etc), and I'm reading all the photos from my device using ALAssetsLibrary.

It works perfectly on iPhone4 iOS 4.2.1, but the same code and the same assets DONT WORK on any 3gs any iOS (from 4.0 to 4.2.1).

The problem is that it retrieves always an invalid CLLocation on the 3gs.

Even on the same picture (copied across both devices) on the iPhone4 returns a valid CLLocation, on the 3gs it returns invalid! The picture image itself it's valid on both devices, only the CLLocation is invalid. I dont have any crashes and the code doesnt step into any invalid blocks, it all works fine apart from the invalid CLLocation data.

Output of the same asset and same code and same iOS version (4.2.1):

iPhone4: <+51.23816667, -0.57700000> +/- 0.00m (speed -1.00 mps / course -1.00) @ 19/02/2011 01:59:28 Greenwich Mean Time

3gs: < nan, nan > +/- 0.00m (speed -1.00 mps / course -1.00) @ 2011-02-19 01:20:35 +0000

(Note also the date on the invalid location is the current time)

Im getting the CLLocation like this:

 CLLocation* location = [asset valueForProperty:ALAssetPropertyLocation];
 CLLocationCoordinate2D coord = [location coordinate];
 if ( !CLLocationCoordinate2DIsValid(coord) ) return;

The ALAssetsLibrary code called in my viewcontroller DidLoad looks like this (totally standard):

ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];

 void (^assetEnumerator)(struct ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
      if(result != NULL) 
      {
                [self myFunction:result withIndex:index];

      }
 };

 void (^assetGroupEnumerator)(struct ALAssetsGroup *, BOOL *) =  ^(ALAssetsGroup *group, BOOL *stop) {
      if(group != nil) 
      {
           numberOfAssets = [group numberOfAssets];
           [group enumerateAssetsUsingBlock:assetEnumerator];
      }
 };     

 [library enumerateGroupsWithTypes:ALAssetsGroupAll
                             usingBlock:assetGroupEnumerator
                           failureBlock: ^(NSError *error) {
                                NSLog(@"Oh no!"); 
                           }];     

One last thing, on the native photo app the pictures are shown in the correct location on the 3gs, so they must have that data somewhere, it just doesnt read it somehow!

I'm not entirely sure it's a device (3gs) problem, normally it never is...

like image 775
Dado Avatar asked Feb 19 '11 10:02

Dado


1 Answers

In iOS 4.0 and higher, you can try using something like this to operate on the ALAsset and retrieve the location data (and more) for a photo asset that is retrieved either by enumerating or using assetForURL:

ALAssetRepresentation *representation = [asset defaultRepresentation];
NSDictionary *metadata = [representation metadata];
NSDictionary *gpsDict = [metadata objectForKey:@"{GPS}"];

NSNumber *latitudeNumber = [gpsDict objectForKey:@"Latitude"];
NSString *latitudeRef = [gpsDict objectForKey:@"LatitudeRef"];

NSNumber *longitudeNumber = [gpsDict objectForKey:@"Longitude"];
NSString *longitudeRef = [gpsDict objectForKey:@"LongitudeRef"];

The latitude and longitude Refs are directions that you will need to translate into positive (N, E) and negative (S, W). You can then use all of that information to build a simple CLLocation. If you need more, log or use the debugger to look at gpsDict (or metadata) and see which keys to use.

Keep in mind that the data is not always there (photos taken in airplane mode) so be sure to check the values.

like image 110
Mark Avatar answered Sep 23 '22 11:09

Mark