Allow me to preface this by saying this is my first time using the ALAssetsLibrary. I need to access the most recent photo in the user's saved photo gallery. It seems that to do this, I have to create an ALAssetsLibrary instance and iterate over every item in the user's gallery before selecting the last image. This is always worst-case scenario. Is there a faster/better way to approach this problem?
4 Answers
You don't have to enumerate all the photos in the user's gallery.
The ALAssetsGroup class has a method - (void)enumerateAssetsAtIndexes:(NSIndexSet *)indexSet options:(NSEnumerationOptions)options usingBlock:(ALAssetsGroupEnumerationResultsBlock)enumerationBlock
which you can use to indicate which assets you want to enumerate.
In your case it's only the last one so set indexSet to [NSIndexSet indexSetWithIndexesInRange:NSMakeRange([group numberOfAssets]-1, [group numberOfAssets])
where group is your ALAssetsGroup.
As @mithuntnt mentioned, you can get the ALAssetsGroup for the photo library using [[assetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop)

- 1,574
- 14
- 33
-
Thanks, you rock! That's just what I was looking for. – Jacob Jul 30 '11 at 16:32
-
1Small bug in the above answer if you're using this. NSMakeRange([group numberOfAssets]-1, [group numberOfAssets]) should be NSMakeRange([group numberOfAssets]-1, 1) (nsmakerange's second param is the count, not the end index). Alternatively, [NSIndexSet indexSetWithIndex:[group numberOfAssets]-1] is slightly more efficient. – Ivo Jansch Oct 30 '12 at 21:38
What about this:
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
*stop = YES;
//...
}
}];

- 520
- 6
- 13
The accepted answer doesn't appear to work if you're enumerating an ALAssetGroup
that you've set a filter on (because [group numberOfAssets]
returns the total assets rather then the total assets after filtering).
I used this:
typedef void(^SMKMostRecentPhotoCompletionBlock)(ALAsset *asset);
- (void)mostRecentPhotoWithCompletionBlock:(SMKMostRecentPhotoCompletionBlock)completionBlock
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
__block ALAsset *mostRecentPhoto = nil;
if (group)
{
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result != NULL)
{
mostRecentPhoto = result;
*stop = YES;
}
}];
}
if (completionBlock)
{
completionBlock(mostRecentPhoto);
}
} failureBlock:^(NSError *error) {
if (completionBlock)
{
completionBlock(nil);
}
}];
}
In your completionBlock
, make sure to check that the returned ALAsset != nil.

- 11,253
- 4
- 35
- 63

- 16,964
- 12
- 68
- 74
There is only one enumeration method. So this is the only way.
I needed the last imported photos. You can have some filter similar to this.
[[assetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if( group )
{
NSString * groupName = [group valueForProperty:ALAssetsGroupPropertyName];
if( [@"Last Import" isEqualToString:groupName] )
{
*stop = true;
...

- 507
- 1
- 5
- 17