Ios – Loading UIImage from UIImagePickerControllerReferenceURL

iosobjective cuiimageuiimagepickercontroller

I am using a UIImagePickerController to allow users to select an image from the image library. I then want to start the location of that file in a sqlite database so I can refer to it later.

I've been doing some googling about how to do this and I'm coming up rather short. I know I can get the ReferenceURL of the item by calling inside the delegate method:

    NSURL *picURL = [info objectForKey:@"UIImagePickerControllerReferenceURL"]

This does give me a valid NSURL object and if I output picURL.absoluteString I can what appears to be a valid url to the assets-library location of the file. However, if I try to create an NSData object with this url so I can in turn create a UIImage, the code fails because NSData returns nil. For example:

    NSURL *picURL = [info objectForKey:@"UIImagePickerControllerReferenceURL"]
    NSString *stringUrl = picURL.absoluteString;
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:stringUrl]];
    imgMain.image = [UIImage imageWithData:data]

I realize I'm being somewhat repetitive here but the point is to grab a string representation of the URL that I can store in sqlite and then use said string later to create an image (so the above code represents that train of thought).

I found some information floating around about using ALAssetsLibrary but that gave me all kinds of fits as it doesn't appear to play nice with iOS 5 and ARC. I keep getting error messages 'Receiver type ALAsset for instance message is a forward declaration. I can set properties on the file that references ALAsset / ALAssetsLibrary to ignore ARC which stops the build error but then as soon as I leave the code block the data goes away. See below:

    NSURL *referenceURL = [info objectForKey:UIImagePickerControllerReferenceURL];
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    __block UIImage *returnValue = nil;
    [library assetForURL:referenceURL resultBlock:^(ALAsset *asset) {
        returnValue = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
    } failureBlock:^(NSError *error) {
       // error handling
    }];
    [library release];

returnValue does return a valid image but as soon as the code exits the resultBlock the contents of the data are gone (i.e. returnValue becomes null again).

So my question is: how do I use the UIImagePickerControllerReferenceURL and convert it to a string I can store in sqlite and then use said string to create a valid UIImage object at a later time?

Best Answer

Looks like you're on the right track, for saving the asset url.

Save
NSURL *picURL = [info objectForKey:@"UIImagePickerControllerReferenceURL"]
NSString *stringUrl = picURL.absoluteString;


Reload AssetURL
NSURL asssetURL = [NSURL URLWithString:stringUrl]

As for loading the asset later on, i'm going to base on the assumption you're not using arc. Which would explain why you're returnValue is nil.

Have you tried adding a retain to the result? for example:

    NSURL *referenceURL = [NSURL URLWithString:savedAssetURLString]
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    __block UIImage *returnValue = nil;
    [library assetForURL:referenceURL resultBlock:^(ALAsset *asset) {
        returnValue = [[UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]] retain]; //Retain Added
    } failureBlock:^(NSError *error) {
       // error handling
    }];
    [library release];
Related Topic