2014-09-22 3 views
42

Как мне получить список всех коллекций, включая рулон камеры (который теперь называется моментом), в iOS8?iOS 8 Фрейм фотографий: Получить список всех альбомов с 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]; 
    }]; 

ответ

117

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

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

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); 
}]; 

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

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

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

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

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

+1

Эй, @Ladislav, отличный ответ. Но как вы узнали, что использовать 'creationDate' для sortDescriptor, являются ли атрибуты фотографий документированными где угодно? – snowbound

+3

На этой странице есть очень хорошая документация от Apple - https://developer.apple.com/library/prerelease/ios/documentation/Photos/Reference/PHFetchOptions_Class/index.html # // apple_ref/doc/uid/TP40014396-CH1-SW5 Посмотрите на sortDescriptors, и вы увидите: «Создайте дескрипторы сортировки со свойствами объектов фотографии, которые вы хотите получить, перечисленные в таблице 1 Например, следующий код сортирует по дате создания, чтобы найти самый старый актив в библиотеке фотографий ». Таблица 1 содержит все свойства, которые вы можете использовать для PHAsset, PHAssetCollection, PHCollectionList, PHCollection ... – Ladislav

+0

Спасибо. Именно то, что я искал! – snowbound

16

Это просто перевод @ превосходным общепринятом ответ Ладислав в в 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)") 
    } 
}) 
+0

Большое вам спасибо! –

+0

Привет @Grimxn, Могу ли я знать, Как получить последние фотографии импорта только в библиотеке фотографий. На основе сортировки даты создания мы также получаем все изображения. Но мое требование заключается только в получении последних импортированных фотографий. потому что мы использовали внешнюю камеру и фотографируем и копируем в IPAD. Итак, как получить «Последний импорт фотографий» в конце приложения? – lakshmanbob

+0

Я сейчас не работаю над этим, но думаю, вам нужно перечислить коллекции активов 'https: // developer.apple.com/documentation/photos/phassetcollection # 1656287' и проверить их' assetCollectionType '. .. – Grimxn

0

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

self.imageArray = [[NSArray Alloc] инициализации];

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];