Reputation: 335
when I launch a photos fetch like:
let assetCollections: PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .Any, options: nil)
I get a result of several albums, so I can iterate through the array and put their titles in a tableView.
BUT: when I use a predicate to filter and get for example the album "Camera Roll", the result is always an empty array: (And I know 100% sure that Camera Roll exists because with nil options it fetches it)
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", "Camera Roll")
let assetCollections: PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .Any, options: fetchOptions)
let album: PHAssetCollection = assetCollections.firstObject as! PHAssetCollection
I've read 4 or 5 different methods by people online, and they all have this predicate whether with "title = %@", or "localizedTitle = %@" or "localizedIdentifier = %@"... I DON'T GET IT. Seems to work for people, not for me. The compiler crashes at the last line trying to "unwrap a nil optional value" ('cos the fetch result is empty). Why is the search returning nil as soon as include the fetch options???
Upvotes: 2
Views: 5620
Reputation: 1498
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "localizedTitle = %@", "Camera Roll")
let assetCollections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
let album = assetCollections.firstObject
Upvotes: 0
Reputation: 1265
If you want Camera Roll album only, you can try something like this :
func getCameraRoll() -> AlbumModel {
var cameraRollAlbum : AlbumModel!
let cameraRoll = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)
cameraRoll.enumerateObjects({ (object: AnyObject!, count: Int, stop: UnsafeMutablePointer) in
if object is PHAssetCollection {
let obj:PHAssetCollection = object as! PHAssetCollection
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
let assets = PHAsset.fetchAssets(in: obj, options: fetchOptions)
if assets.count > 0 {
let newAlbum = AlbumModel(name: obj.localizedTitle!, count: assets.count, collection:obj, assets: assets)
cameraRollAlbum = newAlbum
}
}
})
return cameraRollAlbum
}
Note that you should AlbumModel is a model I created, you can change it and use your own data model.
Upvotes: 0
Reputation: 126127
If you want the Camera Roll album, you're probably better off asking for it symbolically:
let collections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
The SmartAlbumUserLibrary
subtype is how you get the Camera Roll (which isn't always called that).
Upvotes: 6
Reputation: 795
Try the format:
fetchOptions.predicate = NSPredicate(format: "%K == %@", "title", "Camera Roll")
or
fetchOptions.predicate = NSPredicate(format: "%K LIKE[cd] %@", "title", "Camera Roll")
Upvotes: -1
Reputation: 335
the solution seems to be to use:
PHAssetCollection.fetchAssetCollectionsWithLocalizedIdentifiesr(identifiers: [String], options: PHFetchOptions)
So, passing into the parameter 'identifier' an array of strings with the titles of the albums we wish to fetch achieves the same result than attempting the predicate method that doesn't seem to work any more.
Upvotes: 1