问题
I'm trying to use smartAlbum to generate an array of either only videos or only photos or both.
You can see my code below:
PHFetchResult *collectionList = [PHCollectionList fetchMomentListsWithSubtype:PHCollectionListSubtypeMomentListCluster options:nil];
PHFetchOptions *options = nil;
if (self.xSelected) {
options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeImage];
}
if (self.ySelected) {
options = [[PHFetchOptions alloc] init];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeVideo];
}
[collectionList enumerateObjectsUsingBlock:^(PHCollectionList *collection, NSUInteger idx, BOOL *stop) {
PHFetchResult *momentsInCollection = [PHAssetCollection fetchMomentsInMomentList:collection options:options];
for (id moment in momentsInCollection) {
PHAssetCollection *castedMoment = (PHAssetCollection *)moment;
[_smartAlbums insertObject:castedMoment atIndex:0];
}
}];
This however is constantly breaking on the first line inside the block
and giving the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported predicate in fetch options: mediaType == 2'
I did a little research and found this link.
I'm wondering if this is an Apple bug or if its just something wrong with my code.
It seems like it worked for the people that referred to this answer, which is so weird coz its basically the same thing.
Thanks in advance,
Anish
EDIT:
I think I found the answer here in Apple's Documentation. Looks like mediaType is a key only for PHAsset
and not PHAssetCollection
. So now I guess the question is how to get PFAssetCollection
with only videos or only images.
回答1:
Use this method to get photos and videos assets array separately.
Get All Videos
func getAllVideos(completion:@escaping (_ videoAssets : [PHAsset]?) -> Void) {
var videoAssets : [PHAsset] = []
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",ascending: false)]
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
let allVideo = PHAsset.fetchAssets(with: .video, options: fetchOptions)
allVideo.enumerateObjects { (asset, index, bool) in
videoAssets.append(asset)
}
completion(videoAssets)
}
Get All Photos
func getAllPhotos(completion:@escaping (_ photosAssets : [PHAsset]?) -> Void) {
var photosAssets : [PHAsset] = []
let fetchOptions = PHFetchOptions()
let scale = UIScreen.main.scale
let screenWidth = UIScreen.main.bounds.width * scale
let screenHeight = UIScreen.main.bounds.height * scale
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",ascending: false)]
fetchOptions.predicate = NSPredicate(format: "mediaType = %d || (mediaSubtype & %d) != 0 && (pixelHeight != %d AND pixelWidth != %d) OR (pixelHeight != %d AND pixelWidth != %d)", PHAssetMediaType.image.rawValue, PHAssetMediaSubtype.photoLive.rawValue ,screenHeight, screenWidth, screenWidth, screenHeight)
let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
allPhotos.enumerateObjects { (asset, index, bool) in
photosAssets.append(asset)
}
completion(photosAssets)
}
回答2:
No need to put mediaType in predicate In swift 4.0 this is how i used fetchAsset() method from Photos framework , to get all videos from photo library.
You can also get the video from specific folder using predicate.
func fetchAllVideos()
{
//let albumName = "blah"
let fetchOptions = PHFetchOptions()
// fetchOptions.predicate = NSPredicate(format: "title = %@", albumName)
//uncomment this if you want video from custom folder
fetchOptions.predicate = NSPredicate(format: "mediaType = %d ", PHAssetMediaType.video.rawValue )
let allVideo = PHAsset.fetchAssets(with: .video, options: fetchOptions)
allVideo.enumerateObjects { (asset, index, bool) in
// videoAssets.append(asset)
let imageManager = PHCachingImageManager()
imageManager.requestAVAsset(forVideo: asset, options: nil, resultHandler: { (asset, audioMix, info) in
if asset != nil {
let avasset = asset as! AVURLAsset
let urlVideo = avasset.url
print(urlVideo)
}
})
}
}
Hope this help!!!
来源:https://stackoverflow.com/questions/35590640/error-unsupported-predicate-in-fetch-options-mediatype-2