iOS - Get Camera Roll images from ALAssetsLibrary - ios

I managed to get photos from **ALAssetsLibrary** with this code:
-(void)getPhotosFromAssetsLibWithPhotoFilter:(NSString *)filterAlbumString
{
_assets = [#[] mutableCopy];
__block NSMutableArray *tmpAssets = [#[] mutableCopy];
__block NSMutableArray *albumGroup = [#[] mutableCopy];
ALAssetsLibrary *assetsLibrary = [PhotoLibViewController defaultAssetsLibrary];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group != nil)
{
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if(result)
{
if (![filterAlbumString isEqualToString:#""])
{
if ([[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]] isEqualToString:filterAlbumString])
{
[tmpAssets addObject:result];
}
}
else
{
[tmpAssets addObject:result];
}
}
}];
[albumGroup addObject:[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]]];
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([self respondsToSelector:#selector(retrievedPhotoLibrary:)])
{
NSArray *albumGroupReversed = [[albumGroup reverseObjectEnumerator] allObjects];
[self retrievedPhotoLibrary:albumGroupReversed];
}
});
self.assets = [[tmpAssets reverseObjectEnumerator] allObjects];
[self.collectionView reloadData];
}
} failureBlock:^(NSError *error) {
NSLog(#"Error loading images %#", error);
}];
}
I use it like this:
[self getPhotosFromAssetsLibWithPhotoFilter:#"Camera Roll"];
This works great. But the problem is I am localising my app and other languages that is not English does not use "Camera Roll" as the name of the album. I get no images when I use #"Camera Roll".
Is there a name to use that represents Camera Roll ? That will work on every device no matter the language?

Please use ALAssetsGroupSavedPhotos to filter.

Try something like this,
ALAssetsLibrary *al = [[ALAssetsLibrary alloc] init];
[al enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if (asset)
{
// .. do something with the asset
}
}
];
}
failureBlock:^(NSError *error)
{
// User did not allow access to library
//.. handle error
}
];
you can use different source by replacing enumerateGroupsWithTypes.
Second thing ALassetlibrary is deprecated now so you should try PHPhotoLibrary.
Hope this will help :)

Related

iOS - ALAssetsGroupPropertyName returns null album name

I am trying to retrieve all photo album names and all photos with that album name. The album names I got from [group valueForProperty:ALAssetsGroupPropertyName] are mostly correct but there was one album name that says (null) and the album called Favorites does not show.
Album names array:
((null), Camera Roll, Last Import, Nissan Juke, Cam)
Here's my code
-(void)getPhotosFromAssetsLibWithPhotoFilter:(NSString *)filterAlbumString
{
_assets = [#[] mutableCopy];
__block NSMutableArray *tmpAssets = [#[] mutableCopy];
__block NSMutableArray *albumGroup = [#[] mutableCopy];
ALAssetsLibrary *assetsLibrary = [PhotoLibViewController defaultAssetsLibrary];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if(result)
{
if (![filterAlbumString isEqualToString:#""])
{
if ([[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]] isEqualToString:filterAlbumString])
{
[tmpAssets addObject:result];
}
}
else
{
[tmpAssets addObject:result];
}
}
}];
[albumGroup addObject:[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self respondsToSelector:#selector(retrievedPhotoLibrary:)])
{
NSArray *albumGroupReversed = [[albumGroup reverseObjectEnumerator] allObjects];
[self retrievedPhotoLibrary:albumGroupReversed];
}
});
self.assets = [[tmpAssets reverseObjectEnumerator] allObjects];
[self.collectionView reloadData];
} failureBlock:^(NSError *error) {
NSLog(#"Error loading images %#", error);
}];
}
I would like to know why there is a (null) album name and why the album name Favorites does not show.
Thanks.
When the enumeration is done, enumerationBlock is invoked with group set to nil, so you should check each time the group is nil or not and execute reloadData only on the enumeration is done. The proper logic should look like this:
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group != nil)
{
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if(result)
{
if (![filterAlbumString isEqualToString:#""])
{
if ([[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]] isEqualToString:filterAlbumString])
{
[tmpAssets addObject:result];
}
}
else
{
[tmpAssets addObject:result];
}
}
}];
[albumGroup addObject:[NSString stringWithFormat:#"%#", [group valueForProperty:ALAssetsGroupPropertyName]]];
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([self respondsToSelector:#selector(retrievedPhotoLibrary:)])
{
NSArray *albumGroupReversed = [[albumGroup reverseObjectEnumerator] allObjects];
[self retrievedPhotoLibrary:albumGroupReversed];
}
});
self.assets = [[tmpAssets reverseObjectEnumerator] allObjects];
[self.collectionView reloadData];
}
} failureBlock:^(NSError *error) {
NSLog(#"Error loading images %#", error);
}];
For the Favorites, it's a new feature in PhotoKit for iOS8:
With iOS 8, Apple has given us PhotoKit, a modern framework that’s more performant than AssetsLibrary and provides features that allow applications to work seamlessly with a device’s photo library.
Favorite and Hidden Assets
To find out if an asset was marked as favorite or was hidden by the user, just inspect the favorite and hidden properties of the PHAsset instance.
See also: The Photos Framework
So you have to show the Favorites via the PhotoKit framework, check the official sample project: ExampleappusingPhotosframework.zip.

Empty photo album using ALAssetsLibrary causes UIButton to be hidden

I'm using a bit of code to simply be able to set a thumbnail UIButton to be hidden or not, and if it's not hidden, grab the last thumbnail from the ALAssetsGroup and set the UIButton's image to that thumbnail. However this code fails if you create a new photo album in the Photos App, and leave it empty without any photos; it fails because the photo choose UIButton should not be hidden as there is indeed other valid photos in the Photos app to pick from: Here's a screenshot of what I'm describing:
Can anyone help point me in the right direction to solve this? Thanks
Here is the code I'm using from two methods:
- (void)getThumbnailForPhotoLibraryButton
{
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized)
{
[assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group)
{
*stop = YES;
NSArray *photoArray = [self getContentFrom:group withAssetFilter:[ALAssetsFilter allPhotos]];
if (photoArray.count > 0)
{
UIImage *thumbnail = [photoArray objectAtIndex:0];
[self.photoLibraryButton setImage:thumbnail forState:UIControlStateNormal];
self.photoLibraryButton.hidden = NO;
}
else
{
self.photoLibraryButton.hidden = YES;
}
}
}
failureBlock:^(NSError *error)
{}];
}
}
- (NSMutableArray *)getContentFrom:(ALAssetsGroup *)group withAssetFilter:(ALAssetsFilter *)filter
{
NSMutableArray *contentArray = [NSMutableArray array];
[group setAssetsFilter:filter];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if (result)
{
*stop = YES;
[contentArray addObject:[UIImage imageWithCGImage:[result thumbnail]]];
}
}];
return contentArray;
}
As rmaddy pointed out, I was stopping the block too early with a wrong kind of conditional check:
This solved it:
if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized)
{
[assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if (group && group.numberOfAssets >= 1)
{
*stop = YES;
NSArray *photoArray = [self getContentFrom:group withAssetFilter:[ALAssetsFilter allPhotos]];
if (photoArray.count >= 1)
{
UIImage *thumbnail = [photoArray objectAtIndex:0];
[self.photoLibraryButton setImage:thumbnail forState:UIControlStateNormal];
self.photoLibraryButton.hidden = NO;
}
else
{
self.photoLibraryButton.hidden = YES;
}
}
}
failureBlock:^(NSError *error)
{}];
}

photo library loading in ios

I have this static method to return all the photos of my album. The thing is when I run this app, the function runs twice: once returning no images, and once putting the images in the all images array but not getting to the return. I'm confused, what am I doing wrong?
+ (NSMutableArray *)photosAssest
{
NSMutableArray *allImages = [NSMutableArray new];
ALAssetsLibrary *library = AssatLibaryHelper.defaultAssetsLibrary;
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
NSInteger numberOfAssets = [group numberOfAssets];
if (numberOfAssets > 0)
{
for (int i = 0; i <= numberOfAssets-1; i++)
{
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i] options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if (result != nil)
{
UIImage *thumbnail = [UIImage imageWithCGImage:[result thumbnail]];
[allImages addObject:thumbnail];
}
}];
}
}
}
failureBlock:^(NSError *error)
{
}];
return allImages;
}

Get counts of photos and videos in ALAssetGroup

I enumerate my ALAssetGroup like this:
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
if (group.isEditable){
NSLog(#"group is %#", group);
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[groups addObject:group];
}
This filters the group to have only photos included in it's .numberOfAssets. However, I'd like to get both the photos count and the video count. How would I do that without enumerating the whole thing for the 2nd time?
ALAssetsLibrary *al = [[ALAssetsLibrary alloc]init];
[al enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if ([[group valueForProperty:ALAssetsGroupPropertyName]isEqualToString:#"MyAlbumName"]) {
NSLog(#"in album");
int nrAssets=[group numberOfAssets];
__block int countVideo;
__block int countPhoto;
countPhoto=countVideo=0;
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if ([[asset valueForProperty:ALAssetPropertyType]isEqualToString:ALAssetTypeVideo]) {
NSLog(#"eVideo ... count++");
countVideo++;
}
else if(asset valueForProperty:ALAssetPropertyType]isEqualToString:AlAssetTypeVideo]){
NSLog(#"EPhoto ... ");
countPhoto++;
}
}];
}
}
failureBlock:^(NSError *error) { NSLog(#"Boom!!!");}
];
i use this code for a specific album, but you can modify for all albums, hope it helped you :)
The code block below counts all videos and photos:
__block int videoCount = 0;
__block int photoCount = 0;
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc]init];
[assetLibrary
enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group == nil) {
// enumeration complete
return;
}
int total = group.numberOfAssets;
[group setAssetsFilter:[ALAssetsFilter allVideos]];
int groupVideoCount = group.numberOfAssets;
videoCount += groupVideoCount;
photoCount += total - groupVideoCount;
}
failureBlock:^(NSError *error) {
// Handle error
}];

Accessing the image gallery through code for displaying in image view

I've just started a new project where I want the user to be able to pick one of the images in the devices gallery.
I am trying to achieve this by using an ImageView and a UIStepper.
I want to write all images inside the gallery into an array and have the imageView navigate through the array with the + and - buttons of the stepper (selecting the current array position +1 or -1 depending on click).
OK as per prior discussion, here is the project: AssetLibraryPhotosViewer
Have not done an extensive testing, though does seem to run OK both on simulator and real device
#Exothug, to give you an idea of how to enumerate the device library accessing full screen photos:
ALAssetsLibrary* assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group enumerateAssetsUsingBlock:^(ALAsset* asset, NSUInteger index, BOOL* innerstop) {
if (asset) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref scale:rep.scale
orientation:(UIImageOrientation)rep.orientation];
// process the image here
}
}
}];
}
} failureBlock:^(NSError *error) {
NSLog(#"failure: %#", [error localizedDescription]);
}];
you can just process the image via adding it to your array, however depending on number of images in the library it might not be most effective. an alternative approach would be using images URL / indexes to iterate through the library, fetching the image from the library as its needed for display in your ImageView
Maybe try something like this, choose the directory if you want a specific group of images.
NSMutableArray *result = [NSMutableArray array];
[[[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil] enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
NSString *path = [obj lastPathComponent];
[result addObject:path];
];
I thought that , You just need to retrieve the Photos of Camera Roll from Your device .
If so , Try with this :
ALAssetsLibrary
void (^assetEnumerator)(struct ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
}
};
void (^assetGroupEnumerator)(struct ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
};
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(#"Failure");
}];
OR
//Get camera roll images
- (void)updateLastPhotoThumbnail {
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
NSInteger numberOfAssets = [group numberOfAssets];
if (numberOfAssets > 0) {
NSLog(#"numberOfPictures: %d",numberOfAssets);
//NSInteger lastIndex = numberOfAssets - 1;
int i = 0;
for (i = 0; i <= numberOfAssets-1; i++) {
[group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:i] options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
UIImage *thumbnail = [UIImage imageWithCGImage:[result thumbnail]];
NSLog(#"theObject!!!! -- (%d) %#",i,thumbnail);
[cameraRollPictures addObject:thumbnail];
}];
}
}
} failureBlock:^(NSError *error) {
NSLog(#"error: %#", error);
}];

Resources