From eea0163d0d3e5b036c168853847f0e5cd5007c38 Mon Sep 17 00:00:00 2001 From: Arturo Date: Thu, 23 Oct 2014 16:33:41 +0200 Subject: [PATCH 1/3] Correction in tapping control in a cell when the maximum number of selectable elements has been reached This change prevents that when an user tries to select an asset and it has been reached the maximum number of selectable elements, the cellTapped event recognizer accesses to the section of code when an asset is going to be deselected, discounting an element in the ELCConsole's array and causing a problem with the numbering of the indexes Signed-off-by: Arturo --- .../ELCImagePicker/ELCAlbumPickerController.m | 9 ++++++++ Classes/ELCImagePicker/ELCAsset.h | 2 ++ Classes/ELCImagePicker/ELCAsset.m | 9 ++++++++ Classes/ELCImagePicker/ELCAssetCell.m | 23 +++++++++++++------ .../ELCAssetSelectionDelegate.h | 1 + Classes/ELCImagePicker/ELCAssetTablePicker.m | 14 +++++++++++ .../ELCImagePicker/ELCImagePickerController.m | 5 ++++ Classes/ELCImagePickerDemoViewController.m | 4 ++-- 8 files changed, 58 insertions(+), 9 deletions(-) diff --git a/Classes/ELCImagePicker/ELCAlbumPickerController.m b/Classes/ELCImagePicker/ELCAlbumPickerController.m index 8058622..3546e9d 100755 --- a/Classes/ELCImagePicker/ELCAlbumPickerController.m +++ b/Classes/ELCImagePicker/ELCAlbumPickerController.m @@ -111,6 +111,15 @@ - (BOOL)shouldDeselectAsset:(ELCAsset *)asset previousCount:(NSUInteger)previous return [self.parent shouldDeselectAsset:asset previousCount:previousCount]; } +- (BOOL)isSelectableIndexNumber:(NSUInteger)indexNumber { + + if ([self.parent respondsToSelector:@selector(isSelectableIndexNumber:)]) { + return [self.parent isSelectableIndexNumber:indexNumber]; + }else { + return NO; + } +} + - (void)selectedAssets:(NSArray*)assets { [_parent selectedAssets:assets]; diff --git a/Classes/ELCImagePicker/ELCAsset.h b/Classes/ELCImagePicker/ELCAsset.h index b812d77..3775640 100755 --- a/Classes/ELCImagePicker/ELCAsset.h +++ b/Classes/ELCImagePicker/ELCAsset.h @@ -15,6 +15,7 @@ @optional - (void)assetSelected:(ELCAsset *)asset; - (BOOL)shouldSelectAsset:(ELCAsset *)asset; +- (BOOL)isSelectable; - (void)assetDeselected:(ELCAsset *)asset; - (BOOL)shouldDeselectAsset:(ELCAsset *)asset; @end @@ -25,6 +26,7 @@ @property (nonatomic, strong) ALAsset *asset; @property (nonatomic, weak) id parent; @property (nonatomic, assign) BOOL selected; +@property (nonatomic, readonly, getter = isSelectable) BOOL selectable; @property (nonatomic,assign) int index; - (id)initWithAsset:(ALAsset *)asset; diff --git a/Classes/ELCImagePicker/ELCAsset.m b/Classes/ELCImagePicker/ELCAsset.m index a664192..e54b74e 100755 --- a/Classes/ELCImagePicker/ELCAsset.m +++ b/Classes/ELCImagePicker/ELCAsset.m @@ -58,6 +58,15 @@ - (void)setSelected:(BOOL)selected } } +- (BOOL)isSelectable { + + if ([_parent respondsToSelector:@selector(isSelectable)]) { + return [_parent isSelectable]; + }else { + return NO; + } +} + - (NSComparisonResult)compareWithIndex:(ELCAsset *)_ass { if (self.index > _ass.index) { diff --git a/Classes/ELCImagePicker/ELCAssetCell.m b/Classes/ELCImagePicker/ELCAssetCell.m index d456b11..7fd57b2 100755 --- a/Classes/ELCImagePicker/ELCAssetCell.m +++ b/Classes/ELCImagePicker/ELCAssetCell.m @@ -94,21 +94,30 @@ - (void)cellTapped:(UITapGestureRecognizer *)tapRecognizer CGRect frame = CGRectMake(startX, 2, 75, 75); - for (int i = 0; i < [_rowAssets count]; ++i) { + for (int i = 0; i < [_rowAssets count]; ++i) { if (CGRectContainsPoint(frame, point)) { ELCAsset *asset = [_rowAssets objectAtIndex:i]; - asset.selected = !asset.selected; ELCOverlayImageView *overlayView = [_overlayViewArray objectAtIndex:i]; - overlayView.hidden = !asset.selected; - if (asset.selected) { + + // If the asset is not selected check if it could be selected + if (!asset.selected && [asset isSelectable]) { + asset.selected = !asset.selected; + overlayView.hidden = !asset.selected; + asset.index = [[ELCConsole mainConsole] numOfSelectedElements]; [overlayView setIndex:asset.index+1]; [[ELCConsole mainConsole] addIndex:asset.index]; - } - else - { + }else if(asset.selected) { // If the asset is going to be unselected + asset.selected = !asset.selected; + overlayView.hidden = !asset.selected; + + asset.index = 0; + [overlayView setIndex:asset.index]; int lastElement = [[ELCConsole mainConsole] numOfSelectedElements] - 1; [[ELCConsole mainConsole] removeIndex:lastElement]; + }else if (!asset.selected && ![asset isSelectable]) { + // If the asset isn't selected and is not selectable, try to select to show a message to the user + asset.selected = !asset.selected; } break; } diff --git a/Classes/ELCImagePicker/ELCAssetSelectionDelegate.h b/Classes/ELCImagePicker/ELCAssetSelectionDelegate.h index b8dba83..c08cf0d 100755 --- a/Classes/ELCImagePicker/ELCAssetSelectionDelegate.h +++ b/Classes/ELCImagePicker/ELCAssetSelectionDelegate.h @@ -15,5 +15,6 @@ - (void)selectedAssets:(NSArray *)assets; - (BOOL)shouldSelectAsset:(ELCAsset *)asset previousCount:(NSUInteger)previousCount; - (BOOL)shouldDeselectAsset:(ELCAsset *)asset previousCount:(NSUInteger)previousCount; +- (BOOL)isSelectableIndexNumber:(NSUInteger)indexNumber; @end diff --git a/Classes/ELCImagePicker/ELCAssetTablePicker.m b/Classes/ELCImagePicker/ELCAssetTablePicker.m index 24830be..c648e32 100755 --- a/Classes/ELCImagePicker/ELCAssetTablePicker.m +++ b/Classes/ELCImagePicker/ELCAssetTablePicker.m @@ -154,6 +154,20 @@ - (BOOL)shouldSelectAsset:(ELCAsset *)asset return shouldSelect; } +- (BOOL)isSelectable { + + NSUInteger selectionCount = 0; + for (ELCAsset *elcAsset in self.elcAssets) { + if (elcAsset.selected) selectionCount++; + } + + if ([self.parent respondsToSelector:@selector(isSelectableIndexNumber:)]) { + return [self.parent isSelectableIndexNumber:selectionCount]; + }else { + return NO; + } +} + - (void)assetSelected:(ELCAsset *)asset { if (self.singleSelection) { diff --git a/Classes/ELCImagePicker/ELCImagePickerController.m b/Classes/ELCImagePicker/ELCImagePickerController.m index b7f3eda..2ddd7fc 100755 --- a/Classes/ELCImagePicker/ELCImagePickerController.m +++ b/Classes/ELCImagePicker/ELCImagePickerController.m @@ -87,6 +87,11 @@ - (BOOL)shouldDeselectAsset:(ELCAsset *)asset previousCount:(NSUInteger)previous return YES; } +- (BOOL)isSelectableIndexNumber:(NSUInteger)indexNumber { + + return (indexNumber < self.maximumImagesCount); +} + - (void)selectedAssets:(NSArray *)assets { NSMutableArray *returnArray = [[NSMutableArray alloc] init]; diff --git a/Classes/ELCImagePickerDemoViewController.m b/Classes/ELCImagePickerDemoViewController.m index 0b53ef2..92f5706 100644 --- a/Classes/ELCImagePickerDemoViewController.m +++ b/Classes/ELCImagePickerDemoViewController.m @@ -25,8 +25,8 @@ - (IBAction)launchController { ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initImagePicker]; - elcPicker.maximumImagesCount = 100; //Set the maximum number of images to select to 100 - elcPicker.returnsOriginalImage = YES; //Only return the fullScreenImage, not the fullResolutionImage + elcPicker.maximumImagesCount = 8; //Set the maximum number of images to select to 100 + elcPicker.returnsOriginalImage = NO; //Only return the fullScreenImage, not the fullResolutionImage elcPicker.returnsImage = YES; //Return UIimage if YES. If NO, only return asset location information elcPicker.onOrder = YES; //For multiple image selection, display and return order of selected images elcPicker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie]; //Supports image and movie types From 7a669884c4fbf9c5d18f69601569f0f20825b04d Mon Sep 17 00:00:00 2001 From: Arturo Date: Mon, 27 Oct 2014 16:59:20 +0100 Subject: [PATCH 2/3] More efficient control of adding and removing albums and photos Signed-off-by: Arturo --- .../ELCImagePicker/ELCAlbumPickerController.h | 1 + .../ELCImagePicker/ELCAlbumPickerController.m | 234 ++++++++++++++---- Classes/ELCImagePicker/ELCAssetTablePicker.h | 2 +- Classes/ELCImagePicker/ELCAssetTablePicker.m | 22 +- 4 files changed, 203 insertions(+), 56 deletions(-) diff --git a/Classes/ELCImagePicker/ELCAlbumPickerController.h b/Classes/ELCImagePicker/ELCAlbumPickerController.h index 1c41414..15e07fc 100755 --- a/Classes/ELCImagePicker/ELCAlbumPickerController.h +++ b/Classes/ELCImagePicker/ELCAlbumPickerController.h @@ -15,6 +15,7 @@ @property (nonatomic, weak) id parent; @property (nonatomic, strong) NSMutableArray *assetGroups; @property (nonatomic, strong) NSArray *mediaTypes; +@property (strong, nonatomic) ELCAssetTablePicker *picker; // optional, can be used to filter the assets displayed @property (nonatomic, weak) id assetPickerFilterDelegate; diff --git a/Classes/ELCImagePicker/ELCAlbumPickerController.m b/Classes/ELCImagePicker/ELCAlbumPickerController.m index 3546e9d..c3df86f 100755 --- a/Classes/ELCImagePicker/ELCAlbumPickerController.m +++ b/Classes/ELCImagePicker/ELCAlbumPickerController.m @@ -13,6 +13,8 @@ @interface ELCAlbumPickerController () @property (nonatomic, strong) ALAssetsLibrary *library; +@property (nonatomic, strong) NSString *loadedGroupID; +@property (nonatomic, strong) NSMutableArray *tempAssetGroups; @end @@ -37,68 +39,193 @@ - (void)viewDidLoad ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init]; self.library = assetLibrary; - + // Load Albums into assetGroups dispatch_async(dispatch_get_main_queue(), ^ { - @autoreleasepool { - - // Group enumerator Block - void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) - { - if (group == nil) { - return; - } - - // added fix for camera albums order - NSString *sGroupPropertyName = (NSString *)[group valueForProperty:ALAssetsGroupPropertyName]; - NSUInteger nType = [[group valueForProperty:ALAssetsGroupPropertyType] intValue]; - - if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] && nType == ALAssetsGroupSavedPhotos) { - [self.assetGroups insertObject:group atIndex:0]; - } - else { - [self.assetGroups addObject:group]; - } - - // Reload albums - [self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES]; - }; - - // Group Enumerator Failure Block - void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) { - - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[NSString stringWithFormat:@"Album Error: %@ - %@", [error localizedDescription], [error localizedRecoverySuggestion]] delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil]; - [alert show]; - - NSLog(@"A problem occured %@", [error description]); - }; - - // Enumerate Albums - [self.library enumerateGroupsWithTypes:ALAssetsGroupAll - usingBlock:assetGroupEnumerator - failureBlock:assetGroupEnumberatorFailure]; - - } + @autoreleasepool { + + // Group enumerator Block + void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) + { + if (group == nil) { + [self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES]; + return; + } + + // added fix for camera albums order + NSString *sGroupPropertyName = (NSString *)[group valueForProperty:ALAssetsGroupPropertyName]; + NSUInteger nType = [[group valueForProperty:ALAssetsGroupPropertyType] intValue]; + + if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] && nType == ALAssetsGroupSavedPhotos) { + [self.assetGroups insertObject:group atIndex:0]; + } + else { + [self.assetGroups addObject:group]; + } + }; + + // Group Enumerator Failure Block + void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) { + + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[NSString stringWithFormat:@"Album Error: %@ - %@", [error localizedDescription], [error localizedRecoverySuggestion]] delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil]; + [alert show]; + + NSLog(@"A problem occurred %@", [error description]); + }; + + // Enumerate Albums + [self.library enumerateGroupsWithTypes:ALAssetsGroupAll + usingBlock:assetGroupEnumerator + failureBlock:assetGroupEnumberatorFailure]; + + } }); + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkAlbums) name:ALAssetsLibraryChangedNotification object:nil]; } - (void)viewWillAppear:(BOOL)animated { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableView) name:ALAssetsLibraryChangedNotification object:nil]; + self.loadedGroupID = @""; [self.tableView reloadData]; } -- (void)viewWillDisappear:(BOOL)animated { +- (void)didReceiveMemoryWarning { [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; } -- (void)reloadTableView +- (void)dealloc { + + [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; +} + +- (void)checkAlbums { - [self.tableView reloadData]; - [self.navigationItem setTitle:NSLocalizedString(@"Select an Album", nil)]; + if (!self.tempAssetGroups) { + self.tempAssetGroups = [[NSMutableArray alloc] initWithCapacity:0]; + } + [self.tempAssetGroups removeAllObjects]; + + // Load Albums into assetGroups + dispatch_async(dispatch_get_main_queue(), ^ + { + @autoreleasepool { + + // Group enumerator Block + void (^assetGroupEnumeratorCheck)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) + { + if (group == nil) { // End of the enumeration + + NSMutableArray *arrayTemp = [[NSMutableArray alloc] initWithCapacity:1]; + + // Check if an album has been added + for (ALAssetsGroup *group1 in self.tempAssetGroups) { + BOOL albumExists = NO; + NSString *groupID1 = (NSString *)[group1 valueForProperty:ALAssetsGroupPropertyPersistentID]; + + for (ALAssetsGroup *group2 in self.assetGroups) { + NSString *groupID2 = (NSString *)[group2 valueForProperty:ALAssetsGroupPropertyPersistentID]; + + if ([groupID1 isEqualToString:groupID2]) { + albumExists = YES; + break; + } + } + if (!albumExists) { + [arrayTemp addObject: group1]; + } + } + //Add the new albums + if (arrayTemp.count > 0) { + [self.assetGroups addObjectsFromArray:arrayTemp]; + } + [arrayTemp removeAllObjects]; + + // Check if an album has been deleted + for (ALAssetsGroup *group1 in self.assetGroups) { + BOOL albumExists = NO; + NSString *groupID1 = (NSString *)[group1 valueForProperty:ALAssetsGroupPropertyPersistentID]; + + for (ALAssetsGroup *group2 in self.tempAssetGroups) { + NSString *groupID2 = (NSString *)[group2 valueForProperty:ALAssetsGroupPropertyPersistentID]; + + if ([groupID1 isEqualToString:groupID2]) { + albumExists = YES; + break; + } + } + if (!albumExists) { + [arrayTemp addObject:group1]; + } + } + + //Remove the deleted albums + if (arrayTemp.count > 0) { + [self.assetGroups removeObjectsInArray:arrayTemp]; + } + + // If an album is loaded, check if it has been deleted to get back + if (self.loadedGroupID.length > 0) { + BOOL albumExists = NO; + for (ALAssetsGroup *group in self.tempAssetGroups) { + NSString *groupID = (NSString *)[group valueForProperty:ALAssetsGroupPropertyPersistentID]; + if ([groupID isEqualToString:self.loadedGroupID]) { + albumExists = YES; + break; + } + } + + // If the loaded album has been deleted pop the picker viewcontroller + if (!albumExists) { + [self.picker returnBack]; + } + }else { + [self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES]; + } + + return; + } + + // added fix for camera albums order + NSString *sGroupPropertyName = (NSString *)[group valueForProperty:ALAssetsGroupPropertyName]; + NSUInteger nType = [[group valueForProperty:ALAssetsGroupPropertyType] intValue]; + + if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] && nType == ALAssetsGroupSavedPhotos) { + [self.tempAssetGroups insertObject:group atIndex:0]; + } + else { + [self.tempAssetGroups addObject:group]; + } + }; + + // Group Enumerator Failure Block + void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) { + + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:[NSString stringWithFormat:@"Album Error: %@ - %@", [error localizedDescription], [error localizedRecoverySuggestion]] delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil]; + [alert show]; + + NSLog(@"A problem occured %@", [error description]); + }; + + if (!self.library) { + self.library = [[ALAssetsLibrary alloc] init]; + } + + // Enumerate Albums + [self.library enumerateGroupsWithTypes:ALAssetsGroupAll + usingBlock:assetGroupEnumeratorCheck + failureBlock:assetGroupEnumberatorFailure]; + + } + }); +} + +- (void)reloadTableView { + + [self.tableView reloadData]; + [self.navigationItem setTitle:NSLocalizedString(@"Select an Album", nil)]; } - (BOOL)shouldSelectAsset:(ELCAsset *)asset previousCount:(NSUInteger)previousCount @@ -185,15 +312,16 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - ELCAssetTablePicker *picker = [[ELCAssetTablePicker alloc] initWithNibName: nil bundle: nil]; - picker.parent = self; - - picker.assetGroup = [self.assetGroups objectAtIndex:indexPath.row]; - [picker.assetGroup setAssetsFilter:[self assetFilter]]; - - picker.assetPickerFilterDelegate = self.assetPickerFilterDelegate; + self.picker = [[ELCAssetTablePicker alloc] initWithNibName: nil bundle: nil]; + self.picker.parent = self; + self.picker.assetGroup = [self.assetGroups objectAtIndex:indexPath.row]; + [self.picker.assetGroup setAssetsFilter:[self assetFilter]]; + self.picker.assetPickerFilterDelegate = self.assetPickerFilterDelegate; - [self.navigationController pushViewController:picker animated:YES]; + // Store the persistentID of the album to load + self.loadedGroupID = (NSString *)[self.picker.assetGroup valueForProperty:ALAssetsGroupPropertyPersistentID]; + + [self.navigationController pushViewController:self.picker animated:YES]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath diff --git a/Classes/ELCImagePicker/ELCAssetTablePicker.h b/Classes/ELCImagePicker/ELCAssetTablePicker.h index 8148ef6..b7ce5d0 100755 --- a/Classes/ELCImagePicker/ELCAssetTablePicker.h +++ b/Classes/ELCImagePicker/ELCAssetTablePicker.h @@ -23,8 +23,8 @@ // optional, can be used to filter the assets displayed @property(nonatomic, weak) id assetPickerFilterDelegate; +- (void)returnBack; - (int)totalSelectedAssets; -- (void)preparePhotos; - (void)doneAction:(id)sender; diff --git a/Classes/ELCImagePicker/ELCAssetTablePicker.m b/Classes/ELCImagePicker/ELCAssetTablePicker.m index c648e32..ebea7ae 100755 --- a/Classes/ELCImagePicker/ELCAssetTablePicker.m +++ b/Classes/ELCImagePicker/ELCAssetTablePicker.m @@ -51,7 +51,7 @@ - (void)viewDidLoad [self performSelectorInBackground:@selector(preparePhotos) withObject:nil]; // Register for notifications when the photo library has changed - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preparePhotos) name:ALAssetsLibraryChangedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshAssets) name:ALAssetsLibraryChangedNotification object:nil]; } - (void)viewWillAppear:(BOOL)animated @@ -64,6 +64,15 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[ELCConsole mainConsole] removeAllIndex]; +} + +- (void)didReceiveMemoryWarning { + + [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; } @@ -104,7 +113,7 @@ - (void)preparePhotos [self.elcAssets addObject:elcAsset]; } - }]; + }]; dispatch_sync(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; @@ -124,6 +133,15 @@ - (void)preparePhotos } } +- (void)refreshAssets { + + [self performSelectorInBackground:@selector(preparePhotos) withObject:nil]; +} + +- (void)returnBack { + + [self.navigationController popViewControllerAnimated:YES]; +} - (void)doneAction:(id)sender { From be2c4da40f6663aad583efbe55fb6bbb678c016c Mon Sep 17 00:00:00 2001 From: Arturo Date: Mon, 27 Oct 2014 17:43:22 +0100 Subject: [PATCH 3/3] Delete all selected index in ELCConsole array when refreshing images due to a change in the library Signed-off-by: Arturo --- Classes/ELCImagePicker/ELCAssetTablePicker.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Classes/ELCImagePicker/ELCAssetTablePicker.m b/Classes/ELCImagePicker/ELCAssetTablePicker.m index ebea7ae..a41b75c 100755 --- a/Classes/ELCImagePicker/ELCAssetTablePicker.m +++ b/Classes/ELCImagePicker/ELCAssetTablePicker.m @@ -93,6 +93,7 @@ - (void)preparePhotos @autoreleasepool { [self.elcAssets removeAllObjects]; + [[ELCConsole mainConsole] removeAllIndex]; [self.assetGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result == nil) {