Get an Error When Trying to Get All the Photos from Phassetcollection.Fetchassetcollections

Get Specific Photo from Specific Photo Album with PHAssetCollection in Swift 4

You can use this class .

import Foundation
import Photos

class FetchPhotos{

var images:[UIImage] = []
var imageUrl:String!

func fetchPhotos() -> String{
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]

// Fetch the image assets
let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)

// If the fetch result isn't empty,
// proceed with the image request
if fetchResult.count > 0 {
let totalImageCountNeeded = 1 // <-- The number of images to fetch
fetchPhotoAtIndex(0, totalImageCountNeeded, fetchResult)
}
return imageUrl
}

// Repeatedly call the following method while incrementing
// the index until all the photos are fetched
func fetchPhotoAtIndex(_ index:Int, _ totalImageCountNeeded: Int, _ fetchResult: PHFetchResult<PHAsset>) {

let albumName = "CustonAlbum"
// Note that if the request is not set to synchronous
// the requestImageForAsset will return both the image
// and thumbnail; by setting synchronous to true it
// will return just the thumbnail
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true

let collection: PHFetchResult =
PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil)
for k in 0 ..< collection.count {
let obj:AnyObject! = collection.object(at: k)
if obj.title == albumName {
print("Yeap!")

// Perform the image request
PHImageManager.default().requestImage(for: fetchResult.object(at: index) as PHAsset, targetSize: CGSize(width: 1000, height: 1000), contentMode: PHImageContentMode.aspectFill, options: requestOptions, resultHandler: { (image, info) in

if let image = image {
// Add the returned image to your array
self.images += [image]
}
// If you haven't already reached the first
// index of the fetch result and if you haven't
// already stored all of the images you need,
// perform the fetch request again with an
// incremented index
if index + 1 < fetchResult.count && self.images.count < totalImageCountNeeded {
self.fetchPhotoAtIndex(index + 1, totalImageCountNeeded, fetchResult)
} else {
// Else you have completed creating your array
print("Completed array: \(self.images[0])")
print("Image URL \(String(describing: info!["PHImageFileURLKey"]))")
self.imageUrl = "\(info!["PHImageFileURLKey"]!)"
}
})

}}
}

}

PHFetchResult get all photos and sort by date inconsistent

I figured this out on my own, here is my solution:

- (void)setup
{
self.recentsDataSource = [[NSMutableOrderedSet alloc]init];
self.favoritesDataSource = [[NSMutableOrderedSet alloc]init];

PHFetchResult *assetCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum | PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];

PHFetchResult *favoriteCollection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumFavorites options:nil];

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

for (PHAsset *asset in assetsInCollection)
{
[self.recentsDataSource addObject:asset];
}
}

if (self.recentsDataSource.count > 0)
{
NSArray *array = [self.recentsDataSource sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]];

self.recentsDataSource = [[NSMutableOrderedSet alloc]initWithArray:array];
}

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

for (PHAsset *asset in assetsInCollection)
{
[self.favoritesDataSource addObject:asset];
}
}

if (self.favoritesDataSource.count > 0)
{
NSArray *array = [self.favoritesDataSource sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]];

self.favoritesDataSource = [[NSMutableOrderedSet alloc]initWithArray:array];
}
}

How to fetch all images from custom Photo Album - Swift

For Swift 4

using this answer https://stackoverflow.com/a/28904792/4795651 edited a little for myself.

import Photos

func fetchCustomAlbumPhotos()
{
let albumName = "Album Name Here"
var assetCollection = PHAssetCollection()
var albumFound = Bool()
var photoAssets = PHFetchResult<AnyObject>()
let fetchOptions = PHFetchOptions()

fetchOptions.predicate = NSPredicate(format: "title = %@", albumName)
let collection:PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)

if let firstObject = collection.firstObject{
//found the album
assetCollection = firstObject
albumFound = true
}
else { albumFound = false }
_ = collection.count
photoAssets = PHAsset.fetchAssets(in: assetCollection, options: nil) as! PHFetchResult<AnyObject>
let imageManager = PHCachingImageManager()
photoAssets.enumerateObjects{(object: AnyObject!,
count: Int,
stop: UnsafeMutablePointer<ObjCBool>) in

if object is PHAsset{
let asset = object as! PHAsset
print("Inside If object is PHAsset, This is number 1")

let imageSize = CGSize(width: asset.pixelWidth,
height: asset.pixelHeight)

/* For faster performance, and maybe degraded image */
let options = PHImageRequestOptions()
options.deliveryMode = .fastFormat
options.isSynchronous = true

imageManager.requestImage(for: asset,
targetSize: imageSize,
contentMode: .aspectFill,
options: options,
resultHandler: {
(image, info) -> Void in
self.photo = image!
/* The image is now available to us */
self.addImgToArray(uploadImage: self.photo!)
print("enum for image, This is number 2")

})

}
}
}

func addImgToArray(uploadImage:UIImage)
{
self.images.append(uploadImage)

}

For Swift 2.1

import Photos

func FetchCustomAlbumPhotos()
{
var albumName = "SwiftAlbum"
var assetCollection = PHAssetCollection()
var albumFound = Bool()
var photoAssets = PHFetchResult()

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", albumName)
let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)

if let first_Obj:AnyObject = collection.firstObject{
//found the album
assetCollection = collection.firstObject as! PHAssetCollection
albumFound = true
}
else { albumFound = false }
var i = collection.count
photoAssets = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: nil)
let imageManager = PHCachingImageManager()

// let imageManager = PHImageManager.defaultManager()

photoAssets.enumerateObjectsUsingBlock{(object: AnyObject!,
count: Int,
stop: UnsafeMutablePointer<ObjCBool>) in

if object is PHAsset{
let asset = object as! PHAsset
print("Inside If object is PHAsset, This is number 1")

let imageSize = CGSize(width: asset.pixelWidth,
height: asset.pixelHeight)

/* For faster performance, and maybe degraded image */
let options = PHImageRequestOptions()
options.deliveryMode = .FastFormat
options.synchronous = true

imageManager.requestImageForAsset(asset,
targetSize: imageSize,
contentMode: .AspectFill,
options: options,
resultHandler: {
(image, info) -> Void in
self.photo = image!
/* The image is now available to us */
self.addImgToArray(self.photo)
print("enum for image, This is number 2")

})

}
}
}

func addImgToArray(uploadImage:UIImage)
{
self.images.append(uploadImage)

}

PHAssets/PHAssetCollection/PHCollectionList and Folders

With the current developer APIs (PhotoKit) there is no easy way (like with a single request) to list all assets in a folder (and its subfolders/albums). However, you can of recursively enumerate all albums in the folder and it's subfolders and then put the results into a single array. This however can be slow depending on the number of levels and assets contained in the nested structure.
Please note, that a folder on any level can also contain an album (e.g. on "Folder Level 1" there could also be an album in addition to the folder "Folder Level 2").
Apple's Photos App is not using PhotoKit - so I assume they have a way to do this with a single request.



Related Topics



Leave a reply



Submit