Search code examples
objective-cuiimagealassetlibrary

Displaying image from asset library


I'm trying to take an image selected with the imagePickerControl and using the URL provided, open it and display it on a imageview. If I use UIImagePickerControllerOriginalImage to set my image, it works fine, but I don't want to store the image in my database, I just want to store the URL. Before I expanded this further into my code, I wanted to make sure it would work. Bellow is the code that returns the selected image from the PickerController and tries to display the image.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self dismissViewControllerAnimated:YES completion:nil];
    self.imageURL=[info objectForKey:UIImagePickerControllerReferenceURL];
    CCLog(@"Image =%@",[info objectForKey:UIImagePickerControllerReferenceURL]);
//    self.image = [info objectForKey:UIImagePickerControllerOriginalImage];

    ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

    switch(status){
        case ALAuthorizationStatusDenied: {
            CCLog(@"not authorized");
            break;
        }
        case ALAuthorizationStatusRestricted: {
            CCLog(@"Restricted");
            break;
        }
        case ALAuthorizationStatusNotDetermined: {
            CCLog(@"Undetermined");
            break;
        }
        case ALAuthorizationStatusAuthorized: {
            CCLog(@"Authorized");
            CCLog(@"self.imageURL=%@",self.imageURL);
            ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
            __block UIImage *returnValue = nil;
            [library assetForURL:self.imageURL resultBlock:^(ALAsset *asset) {
                returnValue = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
                } failureBlock:^(NSError *error) {
                    NSLog(@"error : %@", error);
            }];
            [self.imageDisplay setImage:returnValue];
            [self.imageDisplay setNeedsDisplay];
            break;
        }
        default: {
            CCLog(@"Unknown hit default");
            break;
        }

    }

    // You have the image. You can use this to present the image in the next view like you require in `#3`.

}

When this runs, returnValue is coming out as nil when I trace it and no image is displayed. I got the code from https://stackoverflow.com/a/13276649/3723298

Thanks


Solution

  • assetForURL:resultBlock:failureBlock: is asynchronous. You want something like this:

        case ALAuthorizationStatusAuthorized: {
            CCLog(@"Authorized");
            CCLog(@"self.imageURL=%@",self.imageURL);
            ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
            [library assetForURL:self.imageURL resultBlock:^(ALAsset *asset) {
                UIImage *returnValue = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.imageDisplay setImage:returnValue];
                    [self.imageDisplay setNeedsDisplay];
                });
            } failureBlock:^(NSError *error) {
                NSLog(@"error : %@", error);
            }];
            break;
        }
    

    BTW - what's the point of this? You get the image much more directly from the image picker delegate method. There is no need to get the image again from the asset library.

    Just do:

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        self.imageDisplay.image = [info objectForKey:UIImagePickerControllerOriginalImage];
    
        [self dismissViewControllerAnimated:YES completion:nil];
    }