display image from URL retrieved from ALAsset in iPhone

The API has changed the rules slightly and you dont get direct file system access to the iPhoto library any more. Instead you get asset library URL’s like this.

assets-library://asset/asset.JPG?id=1000000003&ext=JPG

You use the ALAssetLibrary object to access the ALAsset object via the URL.

so from the docs for ALAssetLibrary throw this in a header (or your source)

typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);

which isnt strictly needed but keeps things pretty.
and then in your source.

-(void)findLargeImage
{
    NSString *mediaurl = [self.node valueForKey:kVMMediaURL];

    //
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            largeimage = [UIImage imageWithCGImage:iref];
            [largeimage retain];
        }
    };

    //
    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };

    if(mediaurl && [mediaurl length] && ![[mediaurl pathExtension] isEqualToString:AUDIO_EXTENSION])
    {
        [largeimage release];
        NSURL *asseturl = [NSURL URLWithString:mediaurl];
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:asseturl 
                       resultBlock:resultblock
                      failureBlock:failureblock];
    }
}

A couple of things to note are that this uses blocks which were new to me before I started my iOS4 porting but you might like to look at

https://www.mikeash.com/pyblog/friday-qa-2008-12-26.html

and

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

They bend your head a little but if you think of them as notification selectors or callbacks it kind of helps.

Also

  • when findLargeImage returns the
    resultblock wont have run yet as its
    a callback. So largeImage wont be
    valid yet.
  • largeImage needs to be an
    instance variable not scoped to the
    method.

I use this construct to do this when using the method but you may find something more suitable to your use.

[node.view findLargeImage];
UIImage *thumb = node.view.largeImage;
if (thumb) { blah blah }

Thats what I learned while trying to get this working anyway.

iOS 5 update

When the result block fires seems to be a bit slower with iOS5 & maybe single core devices so I couldnt rely on the image to be available directly after calling findLargeImage. So I changed it to call out to a delegate.

@protocol HiresImageDelegate <NSObject>
@optional
-(void)hiresImageAvailable:(UIImage *)aimage;
@end

and comme cá

//
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        CGImageRef iref = [rep fullResolutionImage];
        if (iref) {
            UIImage *largeimage = [UIImage imageWithCGImage:iref];
            [delegate hiresImageAvailable:large];
        }
    };

Leave a Comment