1

In my app I allow the user to take photos to associate with a given task. My approach has been to use this category to create an ALAssetsGroup with a custom name and save the photos into it. The problem arises when I go to grab all of those photos and display them as thumbnails. I'm grabbing the assets like this:

- (void)setImagesForTask:(Task *)task {
//clear images associated with the task so we don't double up. 
    [task clearImages]; 
    //static instance of ALAssetsLibrary
        lib = [JobStore defaultAssetsLibrary];
        dispatch_queue_t queue = dispatch_get_main_queue();
        dispatch_async(queue, ^(void){
            [lib enumerateGroupsWithTypes:ALAssetsGroupAlbum
                               usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                                   NSLog(@"group:%@", group);
                                    //find my custom photo album and if it's there, enumerate through it. 
                                   if (group != nil && [[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:
                                                 [NSString stringWithFormat:@"Media for %@", task.title]]) {
                                       if (group.numberOfAssets != 0) {
                                       [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                                           if (result != nil) {
                                               CGImageRef imgRef = [[result defaultRepresentation] fullScreenImage];
                                               UIImage *img = [UIImage imageWithCGImage:imgRef];
                                                //methods to resize the image and get PNG representations…
                                               [task setThumbnailDataFromImage:img];
                                               [task setLargeImageDataFromImage:img];
                                               NSLog(@"saved image to: %@", group);
                                           } else if (result == nil){
                                               NSLog(@"enumeration of assets ended");
                                                }
                                            }];
                                       }
                                    //if the group isn't there...
                                   } else if (group == nil) {
                                    //this method removes a UIView with a UIActivityIndicatorView that appears while enumeration occurs. 
                                       [self performSelectorOnMainThread:@selector(removeView) 
                                                              withObject:nil 
                                                           waitUntilDone:NO];
                                       NSLog(@"enumeration of groups ended");
                                   }}
                             failureBlock:^(NSError *error) {
                                 NSLog(@"FAILURE");
                             }];
        });
    JobStore *js = [JobStore defaultStore];
    [js saveChanges];
}

This is the exception that I get:

2012-04-02 10:05:26.585 MyApp[2746:7d3b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSOrderedSet enumerateObjectsAtIndexes:options:usingBlock:]: index 0 beyond bounds for empty ordered set'

The exception throws at the enumerateAssetsUsingBlock: method. This is particularly prone to happen if I add photos to one task, navigate to another and add photos to that one. One odd thing is that, before the exception is thrown, I have this in my log:

2012-04-02 10:05:26.580 MyApp[2746:707] group:ALAssetsGroup - Name:Media for (current task), Type:Album, Assets count:1

So the asset group isn't actually empty, but when I try to enumerate assets within it, my app seems to think that there is nothing there. It seems to me that, maybe because I have these enumerations nested and/or because the blocks execute in the background but the methods return immediately, that I am attempting to enumerate an assets group before my app knows that it contains anything. Is there a best way to approach this? I think there's something fundamental that I'm not understanding about how the blocks of these methods are executed. Any input would be greatly appreciated.

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
geraldWilliam
  • 4,123
  • 1
  • 23
  • 35
  • Thanks to those of you that viewed this question. I believe I have resolved it and the issue was a bad design decision on my part. I'll post an answer today but can't yet due to not enough rep. – geraldWilliam Apr 02 '12 at 18:35

2 Answers2

0

I found that trying to grab assets from the library using the above enumeration and trying to update the UI based on that was totally unreliable. I rethought my design and now I do this enumeration at app launch to make sure that I have all of the photos that I had taken previously. However, when I take a new photo, I just add that to an NSMutableArray and make my UI changes from that array instead of trying to gather from ALAssetsLibrary all over again. Once my UI is updated, I just save to my custom photo album in the background. This works reliably and is way faster than trying to do this enumeration.

geraldWilliam
  • 4,123
  • 1
  • 23
  • 35
0

The problem with that solution is that if users add photos or do something with their photo library, you won't update easily. Catching notifications and such may make it possible, but still.

I found a way to solve this range exception which I posted here: ALAssetsLibrary seems to return wrong number of my photos

Community
  • 1
  • 1
Kalle
  • 13,186
  • 7
  • 61
  • 76