FIlter alassets by years

I am trying to filter AlAssets by year and month. I can already get dates and filter by year and month, but this is too slow with about 1000 photos. What's the best way to do this?

+ (void) loadFromLibraryByDate:(ALAssetsLibrary *)library assetType:(NSString *)type toArray:(NSMutableArray *)array onTable:(UITableView *)tableView onYear:(NSString *)year onMonth:(NSString *)mouth withDelegate:(id) delegate{

//clean passed objects
[array removeAllObjects];

// filter for the library
NSInteger groupType = ALAssetsGroupAll;



// block to enumerate thought the groups
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock =
^(ALAssetsGroup *group, BOOL *stop){
    if(group){
        [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
            if(asset){
                //                    cachedPhotos = [NSMutableDictionary new];

                if([asset valueForProperty:ALAssetPropertyType] == type){
                    if(year != nil && mouth != nil)
                    {
                        NSDate *date = [asset valueForProperty:ALAssetPropertyDate];
                        if(date.year == [year integerValue] && date.month == [mouth integerValue])
                        {
                            [array addObject:asset];
                        }
                     }
                    else if(year != nil && mouth == nil)
                    {
                        NSDate *date = [asset valueForProperty:ALAssetPropertyDate];
                        NSString *monthName = [date monthName:date.month];
                        if(date.year == [year integerValue])
                        {
                            if(![array containsObject:monthName])
                            {
                                [array addObject:monthName];
                            }
                        }
                    }
                    else
                    {
                        NSDate *date = [asset valueForProperty:ALAssetPropertyDate];
                        NSNumber *yearNum = [NSNumber numberWithInt:date.year];
                        if(![array containsObject:yearNum])
                        {
                            [array addObject:yearNum];
                        }
                    }
                }
            }
        }];
    }
    else{
        if( [delegate respondsToSelector:@selector(didFinishLoadingLibraryByDate:)] ){
            [delegate performSelector:@selector(didFinishLoadingLibraryByDate:)];
        }
        [tableView reloadData];
    }
};

// failure block, what happens if when something wrong happens when enumerating
ALAssetsLibraryAccessFailureBlock failBlock = ^(NSError *error){
    NSLog(@"Error: %@", [error localizedDescription]);

    static dispatch_once_t pred;

    dispatch_once(&pred, ^{

        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *libraryFailure = [[UIAlertView alloc] initWithTitle:@"Serviço de Localização" message:@"Para poder partilhar conteúdos nesta versão iOS, tem de autorizar os serviços de localização. (Definições > Serviços de Localização)" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [libraryFailure show];
            [libraryFailure release];
        });

    });

};

[library enumerateGroupsWithTypes:groupType usingBlock:listGroupBlock failureBlock:failBlock];

      

Any help is appreciated, thanks

+1


source to share


2 answers


I think you are on the right track. I don't know how to filter the metadata other than listing how you do it. Unfortunately, enumerating by asset group is inherently slow on iOS - if you think 1000 is bad, try 10k or 20k assets (not uncommon, I have this on my phone to carry right now).



One way to get around this (not necessarily recommended as it is a lot of work and the potential for errors is very high) is to create your own database of asset timestamps. While the user is otherwise busy (via tutorial or whatever) list all assets and copy the metadata and ALAssetPropertyAssetURL

in whatever format works best for you. Be sure to listen to messages ALAssetsLibraryChangedNotification

if you do.

0


source


You must first list all ALAsset when you start your application and then filter them. Because enumerating ALAsset from the database is so slow, you shouldn't need to iterate over them. Therer is a notification, a faster repetition of ALAsset than the first. Apple should optimize the library.



0


source







All Articles