Padin215
Padin215

Reputation: 7484

Issue with a block and waiting for it to finish

i'm retrieving an image with UIImagePickerController and i need to check if it has gps metadata in it or not. this code will pull it out but i'm having an issue with timing with the block. Since i'm using a block on the assetLibrary, it will complete at a later time (abit, fractions of a second).

if ([info objectForKey:UIImagePickerControllerReferenceURL])
{
    [self performSelectorOnMainThread:@selector(testMethod:) withObject:[info objectForKey:UIImagePickerControllerReferenceURL] waitUntilDone:YES];

    NSLog(@"self.metadataDictionary back in impagepickerdidfinish: %@", self.metadataDictionary);
}

}

-(void)testMethod:(NSURL *) photoURL
{        
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

        [library assetForURL:photoURL resultBlock:^(ALAsset *asset) {
            ALAssetRepresentation *representation = [asset defaultRepresentation];
            NSDictionary *metadataDict = [representation metadata]; 
            self.metadataDictionary = metadataDict;
            NSLog(@"self.metadataDictionary in block: %@", self.metadataDictionary);

        } failureBlock:^(NSError *error) {
            NSLog(@"%@",[error description]);
        }];
}

the line

NSLog(@"self.metadataDictionary back in impagepickerdidfinish: %@", self.metadataDictionary);

2012-03-21 16:40:47.110[9387:707] self.metadataDictionary back in impagepickerdidfinish: (null)
2012-03-21 16:40:47.265[9387:707] self.metadataDictionary in block: {
    ColorModel = RGB;
}

runs before the block is complete and logs as (null).

i thought calling it on the main thread would make it wait until the block was finished, but it doesn't.

any ideas how i can get the app to wait till the block is complete?

Upvotes: 1

Views: 1699

Answers (1)

Ash Furrow
Ash Furrow

Reputation: 12421

The assetForURL:resultBlock:failureBlock: isn't synchronously invoked like NSArray's enumerateObjectsUsingBlock:. It's more like using dispatch_async - the block will be invoked, but not necessarily right away.

What I would do is create another method that your result block invokes to let the rest of your app know that everything is finished. I don't believe there is any way to make this call block the thread until completion - and nor should there be:

When the ALAsset is requested, the user may be asked to confirm the application's access to the data.

You don't want the rest of the main thread blocked while the user confirms or denies access to your application. This is why it's an asynchronous invocation.

Upvotes: 2

Related Questions