FIlter alassets by year

十年热恋 提交于 2019-12-08 08:00:02

问题


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

+ (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 appreciated, thanks


回答1:


I think you're on the right track. There is no way I know of to filter on metadata except by enumerating the way you are doing it. Unfortunately, enumerating through asset groups is just inherently slow on iOS -- if you think 1000 is bad, try 10k or 20k assets (not at all uncommon, I have that on my carry phone right now).

One way around this (not necessarily advised, as it's a lot of work and the bug potential is very high) is to build your own database of asset timestamps. While the user is otherwise busy (with a tutorial or something), enumerate over all the assets and copy the metadata and ALAssetPropertyAssetURL to whatever format works best for you. Don't forget to listen for ALAssetsLibraryChangedNotification messages if you do this.




回答2:


You should enumerate all ALAsset first When App launching,and then filter them. Because Enumerating ALAsset from database is so slow, so you should not reenumerate them again. Therer is a notice, reenumerate ALAsset more faster then the first. Apple should optimize the library.



来源:https://stackoverflow.com/questions/18575691/filter-alassets-by-year

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!