Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store assets with asynchronous enumerator in ALAssetsLibrary?

I'm trying to pull all images from the photos library. The problem is that the method [ALAssetsGroup enumerateAssetsUsingBlock:] is asynchronous so by the time I'm trying to use the assets the enumerator has not started populating my assets array. Here's my code:

        NSMutableArray* photos = [[NSMutableArray alloc] init];

        void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if(result != nil) {
                if(![assetURLDictionaries containsObject:[result valueForProperty:ALAssetPropertyURLs]]) {
                    if(![[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
                        UIImage* img = [UIImage imageWithCGImage:[[result defaultRepresentation] fullScreenImage]];

                        MyPhoto *photo;
                        photo = [MyPhoto photoWithImage:img];
                        [photos addObject:photo];
                    }
                }
            }
        };

        [[assetGroups objectAtIndex:1] enumerateAssetsUsingBlock:assetEnumerator];

        self.photos = photos;
        NSLog(@"Self.Photos %@", self.photos);

After this block runs self.photos is empty. I'm guessing it's because the enumerator block executes in another thread and photos is empty in the assignment self.photos = photos? Any ideas?

like image 503
user1077213 Avatar asked Dec 05 '25 16:12

user1077213


1 Answers

As you say, it's asynchronous, so you need to do the final assignment asynchronously. When the enumerator has exhausted the assets, it will return nil as the result. This happens exactly once and always as the last action of the enumeration. So the recommended pattern is:

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if(result != nil) {
        // ... process result ...
        [photos addObject:photo];
    }
    else {
        // terminating
        self.photos = photos
        NSLog(@"Self.Photos %@", self.photos);

        // you can now call another method or do whatever other post-assign action here
    }
};
like image 167
Eric Brochu Avatar answered Dec 07 '25 17:12

Eric Brochu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!