Подтвердить что ты не робот

Основы iOS 8 Photos: получите список всех альбомов с iOS8

Как мне получить список всех коллекций, включая рулон камеры (который теперь называется моментом), в iOS8?

В iOS 7 я использую блок перечисления ALAssetGroup, но это не включает моменты iOS, которые, похоже, эквивалентны Camera Roll в iOS7.

    void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
    {
        if (group == nil) {// We're done enumerating
            return;
        }

        [group setAssetsFilter:[ALAssetsFilter allAssets]];
        if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] && nType == ALAssetsGroupSavedPhotos) {
            [_assetGroups insertObject:group atIndex:0];
        } else {
            [_assetGroups addObject:group];
        }
    };

    // Group Enumerator Failure Block
    void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
        SMELog(@"Enumeration occured %@", [error description]);
    };

    // Enumerate Albums
    [_library enumerateGroupsWithTypes:kSupportedALAlbumsMask
                            usingBlock:assetGroupEnumerator
                          failureBlock:assetGroupEnumberatorFailure];
    }];
4b9b3361

Ответ 1

Использование Photos Framework немного отличается, вы можете добиться того же результата, но вам просто нужно сделать это по частям.

1) Получите все фотографии (Моменты в iOS8 или Camera Roll раньше)

PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

Необязательно, если вы хотите, чтобы они были упорядочены по дате создания, вы просто добавляете PHFetchOptions так:

PHFetchOptions *allPhotosOptions = [PHFetchOptions new];
allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:allPhotosOptions];

Теперь, если вы хотите, вы можете получить активы из объекта PHFetchResult:

[allPhotosResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
    NSLog(@"asset %@", asset);
}];

2) Получите все альбомы пользователей (с дополнительным видом, например, чтобы показывать только альбомы с хотя бы одной фотографией)

PHFetchOptions *userAlbumsOptions = [PHFetchOptions new];
userAlbumsOptions.predicate = [NSPredicate predicateWithFormat:@"estimatedAssetCount > 0"];

PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:userAlbumsOptions];

[userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
        NSLog(@"album title %@", collection.localizedTitle);
}];

Для каждого PHAssetCollection, возвращаемого из PHFetchResult *userAlbums, вы можете выбрать PHAssets так (вы можете даже ограничить результаты включением только фотоакций):

PHFetchOptions *onlyImagesOptions = [PHFetchOptions new];
onlyImagesOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %i", PHAssetMediaTypeImage];
PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:collection options:onlyImagesOptions];

3) Получите умные альбомы

PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
[smartAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
        NSLog(@"album title %@", collection.localizedTitle);
}];

В смарт-альбомах следует отметить, что collection.estimatedAssetCount может возвращать NSNotFound, если оценкаAssetCount не может быть определена. Как видно из названия, это оценивается. Если вы хотите быть уверенным в количестве активов, вы должны выполнить выборку и получить значение count:

PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];

количество активов = assetsFetchResult.count

У Apple есть пример проекта, который делает то, что вы хотите:

https://developer.apple.com/library/content/samplecode/UsingPhotosFramework/ExampleappusingPhotosframework.zip (для этого вы должны быть зарегистрированным разработчиком)

Ответ 2

Это просто перевод превосходного принятого ответа @Ladislav на Swift:

// *** 1 ***
// Get all photos (Moments in iOS8, or Camera Roll before)
// Optionally if you want them ordered as by creation date, you just add PHFetchOptions like so:
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]

let allPhotosResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: allPhotosOptions)

// Now if you want you can get assets from the PHFetchResult object:
allPhotosResult.enumerateObjectsUsingBlock({ print("Asset \($0.0)") })

// *** 2 ***
// Get all user albums (with additional sort for example to only show albums with at least one photo)
let userAlbumsOptions = PHFetchOptions()
userAlbumsOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0")

let userAlbums = PHAssetCollection.fetchAssetCollectionsWithType(PHAssetCollectionType.Album, subtype: PHAssetCollectionSubtype.Any, options: userAlbumsOptions)

userAlbums.enumerateObjectsUsingBlock( {
    if let collection = $0.0 as? PHAssetCollection {
        print("album title: \(collection.localizedTitle)")
        //For each PHAssetCollection that is returned from userAlbums: PHFetchResult you can fetch PHAssets like so (you can even limit results to include only photo assets):
        let onlyImagesOptions = PHFetchOptions()
        onlyImagesOptions.predicate = NSPredicate(format: "mediaType = %i", PHAssetMediaType.Image.rawValue)
        if let result = PHAsset.fetchKeyAssetsInAssetCollection(collection, options: onlyImagesOptions) {
            print("Images count: \(result.count)")
        }
    }
} )

// *** 3 ***
// Get smart albums

let smartAlbums = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .AlbumRegular, options: nil) // Here you can specify Photostream, etc. as PHAssetCollectionSubtype.xxx
smartAlbums.enumerateObjectsUsingBlock( {
    if let assetCollection = $0.0 as? PHAssetCollection {
        print("album title: \(assetCollection.localizedTitle)")
        // One thing to note with Smart Albums is that collection.estimatedAssetCount can return NSNotFound if estimatedAssetCount cannot be determined. As title suggest this is estimated. If you want to be sure of number of assets you have to perform fetch and get the count like:

        let assetsFetchResult = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: nil)
        let numberOfAssets = assetsFetchResult.count
        let estimatedCount =  (assetCollection.estimatedAssetCount == NSNotFound) ? -1 : assetCollection.estimatedAssetCount
        print("Assets count: \(numberOfAssets), estimate: \(estimatedCount)")
    }
} )

Ответ 3

Попробуйте этот код...

self.imageArray = [[NSArray alloc] init];

PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
requestOptions.synchronous = true;
PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];

NSLog(@"%d",(int)result.count);

    PHImageManager *manager = [PHImageManager defaultManager];
    NSMutableArray *images = [NSMutableArray arrayWithCapacity:countValue];

    // assets contains PHAsset objects.

    __block UIImage *ima;
    for (PHAsset *asset in result) {
        // Do something with the asset

        [manager requestImageForAsset:asset
                           targetSize:PHImageManagerMaximumSize
                          contentMode:PHImageContentModeDefault
                              options:requestOptions
                        resultHandler:^void(UIImage *image, NSDictionary *info) {
                            ima = image;

                            [images addObject:ima];

                        }];




    self.imageArray = [images copy];