PHPhotoLibrary get album names
Asked Answered
B

3

5

I've been trying to find an alternative for getting the album names with the Photos API in iOS 8. With ALAssets, we can use: valueForProperty:ALAssetsGroupPropertyName however with the Photos API, I can't seem to find an alternative. There is: localizedTitle under PHAssetCollection but that isn't right either, it just gives me the city names. I'm looking for something that can return the actual names of the groups, including ones synced with iTunes.

I'd appreciate any help to see how you do this in your apps. Apple is encouraging us to only use the Photos API for apps linked with 8.0, so I'd rather not use both ALAssetLibrary and Photos.

Code:

- (NSString *)nameForAlbumInCollection:(id)collection
{
    NSString *title = nil;

    if ([PHAsset class])
    {
        title = [collection localizedTitle];
    }
    else
    {
        title = [collection valueForProperty:ALAssetsGroupPropertyName];
    }

    return title;
}

- (void)setup
{
    self.recentsCollectionDataSource = [[NSMutableOrderedSet alloc]init];
    self.favoritesCollectionDataSource = [[NSMutableOrderedSet alloc]init];
    self.albumsTableDataSource = [[NSMutableOrderedSet alloc]init];

    NSMutableArray *segmentTitles = [[NSMutableArray alloc]init];

    self.assetsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum | PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];

    if (!self.parentController.canTakeOrChooseVideo)
    {
        fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %i",PHAssetMediaTypeImage];
    }

    for (PHAssetCollection *sub in self.assetsFetchResult)
    {
        PHFetchResult *assetsInCollection = [PHAsset fetchAssetsInAssetCollection:sub options:nil];

        for (PHAsset *asset in assetsInCollection)
        {
            NSLog(@"%@",[self nameForAlbumInCollection:sub]);

            [self.recentsCollectionDataSource addObject:asset];

            if (![segmentTitles containsObject:@"Recents"])
            {
                [segmentTitles addObject:@"Recents"];
                [segmentTitles addObject:@"Albums"];
            }

            if (asset.isFavorite)
            {
                [self.favoritesCollectionDataSource addObject:asset];

                if (![segmentTitles containsObject:@"Favorites"])
                {
                    [segmentTitles addObject:@"Favorites"];
                }
            }
        }
    }
}
Bedight answered 2/6, 2015 at 20:20 Comment(5)
Can you show some results for localizedTitle property of PHAssetCollection in your case because i have been using it and it works just fine for me?Laney
Can you also add nameForAlbumInCollection method as that is the main method & also provide with what output the above program is giving? Also there are a lot of issues with the above code. (not using fetchOptions, creating titles all by yourself etc.)Laney
They arent issues in my code, I'm building my own data source of just the assets.Bedight
Can you provide this method definition? nameForAlbumInCollection?Laney
Added medthod definitionBedight
B
11

This is how I made a list of the album names in a project of mine. You may have to deviate a bit, but this should work.

NSArray *collectionsFetchResults;
NSMutableArray *localizedTitles = [[NSMutableArray alloc] init];

PHFetchResult *smartAlbums = [PHAssetCollection       fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
                                                                      subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
PHFetchResult *syncedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
                                                                subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil];
PHFetchResult *userCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];

// Add each PHFetchResult to the array
collectionsFetchResults = @[smartAlbums, userCollections, syncedAlbums];

for (int i = 0; i < collectionsFetchResults.count; i ++) {

    PHFetchResult *fetchResult = collectionsFetchResults[i];

    for (int x = 0; x < fetchResult.count; x ++) {

        PHCollection *collection = fetchResult[x];
        localizedTitles[x] = collection.localizedTitle;

    }
}
Burnell answered 3/6, 2015 at 16:11 Comment(5)
This doesn't seem to work with photos synced through iTunes/iPhoto/Photos. Unless I'm doing something wrong.Bedight
Oh, my bad. I didn't read your initial post thoroughly. Try adding another PHFetchResult with PHAsssetCollectionSubTypeAlbumSyncedAlbum.Burnell
Wouldn't a dual bitmask work? Ex: PHAssetCollectionTypeSmartAlbum | PHAssetCollectionTypeAlbumBedight
I tried to use a bitmask, but I would get nil when accessing the localizedTitle property. However, I could be using in incorrectly.Burnell
I also got the same error, so no worries! Doing it seperately is fine.Bedight
L
0

I think what you might be using is localizedLocationNames property of PHCollectionList. You should use localizedTitle under PHAssetCollection as you have mentioned in the question.

I wrote a little utility class and added the following method to it for retrieving album name.

+ (NSString *)localizedTitleForGroupOrCollection:(id)collection {
    NSString *title = nil;
    if ([PHAsset class]) {
        title = [collection localizedTitle];
    } else {
        title = [collection valueForProperty:ALAssetsGroupPropertyName];
    }

    return title;
}
Laney answered 3/6, 2015 at 6:46 Comment(3)
Nope, I'm using the localizedTitle property. Also this code isn't working. for (PHAssetCollection *sub in self.assetsFetchResult) { PHFetchResult *assetsInCollection = [PHAsset fetchAssetsInAssetCollection:sub options:fetchOptions]; for (PHAsset *asset in assetsInCollection) { NSLog(@"%@",[self localizedTitleForGroupOrCollection:sub]); }}Bedight
Can you add some more of your class code in the question? Would be really helpful to solve the issue at hand.Laney
I just updated my question with the code I've been using. Thank youBedight
G
0

The bitmask won't work as PHAssetCollectionTypeAlbum, PHAssetCollectionTypeSmartAlbum and PHAssetCollectionTypeMoment are not specified as bit fields. They take values 1, 2, 3. For a bitmask to work they would have to take values 1, 2, 4, which each value being on a different bit.

Goof answered 5/6, 2017 at 22:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.