How to access smart folder from gallery using ALAsset - objective-c

I am making an app where I want to get the list of all albums name from gallery including smart folders(favorites, screenshots. this is an old app where we have used ALAsset in order to access the gallery in our app.
Is there any way through which we can access smart folders as well using ALAssetLibrary?

This code is help.
#import <AssetsLibrary/AssetsLibrary.h>
#property (nonatomic, strong) ALAssetsLibrary *_assetsLibrary;
- (ALAssetsLibrary *)defaultAssetsLibrary {
static dispatch_once_t pred = 0;
static ALAssetsLibrary *library = nil;
dispatch_once(&pred, ^{
library = [[ALAssetsLibrary alloc] init];
});
return library;
}
-(void) getgalleryPic
{
if (self.photos == nil) {
self.photos = [[NSMutableArray alloc] init];
}else
{
[self.photos removeAllObjects];
}
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusAuthorized) {
// Access has been granted.
NSMutableArray *collector = [[NSMutableArray alloc] initWithCapacity:0];
ALAssetsLibrary *library = [self defaultAssetsLibrary];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if (asset) {
[collector addObject:asset];
}else
{
self.photos = [[[collector reverseObjectEnumerator] allObjects] mutableCopy];
NSLog(#"photo lenght %lu",(unsigned long)[self.photos count]);
[_collectionVW reloadData];
}
}];
}
failureBlock:^(NSError *error) { NSLog(#"Boom!!!");}
];
}
else if (status == PHAuthorizationStatusDenied) {
// Access has been denied.
}
else if (status == PHAuthorizationStatusNotDetermined) {
// Access has not been determined.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
// Access has been granted.
NSMutableArray *collector = [[NSMutableArray alloc] initWithCapacity:0];
ALAssetsLibrary *library = [self defaultAssetsLibrary];
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if (asset) {
[collector addObject:asset];
}else
{
self.photos = [[[collector reverseObjectEnumerator] allObjects] mutableCopy];
NSLog(#"photo lenght %lu",(unsigned long)[self.photos count]);
[_collectionVW reloadData];
}
}];
}
failureBlock:^(NSError *error) { NSLog(#"Boom!!!");}
];
}
else {
// Access has been denied.
}
}];
} else if (status == PHAuthorizationStatusRestricted) {
// Restricted access - normally won't happen.
}
}

Related

NSMutableArray writeToURL:url atomically:YES

I'm trying to create a file with an NSMutableArray with just NSStrings stringWithFormat objects inside, this is what i got:
- (IBAction)CreateMod:(id)sender {
NSLog(#"Finished Button Pressed");
NSString* CustomScript = [NSString stringWithFormat:#"//Made with UltimateMM \n %#",self.CS ];
NSArray* fileTypes = [[NSArray alloc] initWithObjects:#"js", nil];
NSSavePanel *spanel = [NSSavePanel savePanel];
[spanel setCanCreateDirectories:YES];
[spanel setCanSelectHiddenExtension:YES];
[spanel setAllowedFileTypes:fileTypes];
[spanel setTreatsFilePackagesAsDirectories:YES];
[spanel beginSheetModalForWindow:self.SecondaryWindow completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton)
{
NSURL *saveURL = [spanel URL];
NSLog(#"%#", saveURL);
NSError* error = nil;
if(_CST == true) {
NSLog(#"CustomScriptMade");
/*
BOOL didWrite = [CustomScript writeToURL:saveURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (didWrite == NO)
{
NSLog(#"CustomScript Write Error");
}
*/
}
if(_TTT == true) {
NSLog(#"TopicMade");
BOOL didWrite = [_TopicPR writeToURL:saveURL atomically:YES];
if (didWrite == NO)
{
NSLog(#"Topic Write Error");
}
}
_CST = false;
_TTT = false;
}
}];
}
I have the CustomScript writeToURL out so i can see if it crates the TopicPR, but it doesn't even open the NSSavePanel, Please Help.
thanks in advance!..

Updating PSTCollectionView contents while loading photos

I'm using PSTCollectionView class to load the photos from iPhone camera roll. I want the photos to appear while they're loaded though, not wait until everything is read. My code looks like this:
-(void) loadAssetGroups {
void (^assetGroupEnumerator)
(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
NSLog(#"group....%#",[group valueForProperty:ALAssetsGroupPropertyName]);
[self loadAssetForGroup:group];
}
};
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
NSLog(#"A problem occured. Error: %#", error.localizedDescription);
};
[[ImagePickerViewController defaultAssetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:assetGroupEnumberatorFailure];
}
-(void) loadAssetForGroup:(ALAssetsGroup*)group {
ALAssetsFilter *filter = [ALAssetsFilter allPhotos];
[group setAssetsFilter:filter];
__block NSMutableArray *indexes = [NSMutableArray arrayWithCapacity:0];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result == nil)
{
return;
}
if (![self.allPhotos containsObject:result]) {
[self.assets setValue:result forKey:[result valueForProperty:ALAssetPropertyURLs]];
[self.allPhotos addObject:result];
[indexes addObject:[NSIndexPath indexPathForItem:[self.allPhotos count]-1 inSection:0]];
[self.collectionView performSelectorOnMainThread:#selector(insertItemsAtIndexPaths:) withObject:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:self.allPhotos.count-1 inSection:0]] waitUntilDone:NO];
}
}];
}
From the console I see that collectionView is calling its dataSource method cellForItemAtIndexPath for the first few objects (that would be visible on the screen) but I need to wait for all photos to be read until I see the collectionView refreshed.
Is there a way to have it running more "on the go"?

How to load several photos with assetForURL with a list of URLs

For a list of URLs I need to load the photos with ALAssetsLibrary:assetForURL, and this within one method.
Since this method works async but it is not iterating over the passed list of URLs, as we all know.
I found this snippet (which should work):
- (void)loadImages:(NSArray *)imageUrls loadedImages:(NSArray *)loadedImages callback: (void(^)(NSArray *))callback
{
if (imageUrls == nil || [imageUrls count] == 0) {
callback(loadedImages);
}
else {
NSURL *head = [imageUrls head];
__unsafe_unretained id unretained_self = self;
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library assetForURL:head resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *assetRepresentation = asset.defaultRepresentation;
UIImage *image = [UIImage imageWithCGImage:assetRepresentation.fullResolutionImage scale:assetRepresentation.scale orientation:(UIImageOrientation)assetRepresentation.orientation];
[unretained_self loadImages:[imageUrls tail] loadedImages:[loadedImages arrayByAddingObject:image] callback:callback];
} failureBlock:^(NSError *error) {
[unretained_self loadImages:[imageUrls tail] loadedImages:loadedImages callback:callback];
}];
}
}
How do I write the method definition in the form (above all the callback)
void loadImages(NSArray *imageUrls, NSArray *loadedImages, ...) ?
How do I call this method from another method (again mainly the callback part) ?
Can the callback be in the calling method or a 3rd method needed for this? and how does this method need to be written?
I have found the snippet here: http://www.calebmadrigal.com/functional-programming-deal-asynchronicity-objective-c/
Use NSThread to call the loadImages method.
NSMutableArray *imageCollection = [NSThread detachNewThreadSelector:#selector (loadImages:)
toTarget:self
withObject:imageUrlsCollection];
- (NSMutableArray *)loadImages:(NSArray *)imageUrls
{
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
NSMutableArray *loadedImages = [[NSMutableArray alloc] init];
#try
{
for(int index = 0; index < [imageUrls count]; index++)
{
NSURL *url = [imageUrls objectAtIndex:index];
[library assetForURL:url resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *assetRepresentation = asset.defaultRepresentation;
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithCGImage:assetRepresentation.fullResolutionImage scale:assetRepresentation.scale orientation:(UIImageOrientation)assetRepresentation.orientation];
[loadedImages addObject:image];
});
} failureBlock:^(NSError *error) {
NSLog(#"Failed to get Image");
}];
}
}
#catch (NSException *exception)
{
NSLog(#"%s\n exception: Name- %# Reason->%#", __PRETTY_FUNCTION__,[exception name],[exception reason]);
}
#finally
{
return loadedImages;
}
}
Note: With ARC,take care about invalid attempt to access ALAssetPrivate past the lifetime of its owning ALAssetsLibrary issue
Here is the fix :)

Get camera roll images and their EXIF data?

I figured out how to get all the user's images in the camera roll using the AssestsLibrary:
- (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);
}];
}
I successfully created the array of UIIMages, but how could I get EXIF data from the UIImages using this snippet I have?
PS: I've looked at this http://code.google.com/p/iphone-exif, but I cannot get it to build without errors.
You can't get metadata from UIImage objects.
But you can query an ALasset object for metadata:
NSDictionary *metadata = [[result defaultRepresentation] metadata];
Chefs,
Hendrik

ios assets not work on ios5

here is my code:
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(#"Failure");
}];
my previous code is this:
assets = [[NSMutableArray alloc] init];
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
NSLog(#"See Asset: %#", result);
[assets addObject:result];
}
};
void (^assetGroupEnumerator)( ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
[self.tableView reloadData];
};
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
and with my phone (ios5) doesn't work, can't go to the assetGroupEnumerator...
also in the simulator, the same thing....
any ideas?
thanks in advance
Are you releasing your ALAssetsLibrary before you are done displaying the assets? You need to retain the library throughout the lifetime of the groups and assets you are using.