FetchAssetsWithLocalIdentifiers返回空数组(FetchAssetsWithLocalIdentifiers returns empty array)
我正在使用
Photos.Framework
将从相机拍摄的照片保存到我的图库中并检索它们。这是我用来存储照片的代码:
__block PHAssetCollection *album = [self getMyAlbumWithName:@"MyAlbumName"]; if(album == nil) { [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) { album = [self getMyAlbumWithName:@"MyAlbumName"]; [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) { _imageLocalIdentifier = imageId; } onError:^(NSError *error) { // No need to do anything }]; } onError:^(NSError *error) { // No need to do anything }]; } else { [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) { _imageLocalIdentifier = imageId; } onError:^(NSError *error) { // No need to do anything }]; } -(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName { PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; NSLog(@"assetCollections.count = %lu", assetCollections.count); if (assetCollections.count == 0) return nil; __block PHAssetCollection * myAlbum; [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) { NSLog(@"album:%@", album); NSLog(@"album.localizedTitle:%@", album.localizedTitle); if ([album.localizedTitle isEqualToString:AlbumName]) { myAlbum = album; *stop = YES; } }]; if (!myAlbum) return nil; return myAlbum; } -(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError { //Check weather the album already exist or not if (![self getMyAlbumWithName:title]) { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // Request editing the album. PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title]; // Get a placeholder for the new asset and add it to the album editing request. PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection]; if (placeHolder) { onSuccess(placeHolder.localIdentifier); } } completionHandler:^(BOOL success, NSError *error) { NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); if (error) { onError(error); } }]; } } -(void)addNewAssetWithImage:(UIImage *)image toAlbum:(PHAssetCollection *)album onSuccess:(void(^)(NSString *ImageId))onSuccess onError: (void(^)(NSError * error)) onError { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // Request creating an asset from the image. PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; // Request editing the album. PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album]; // Get a placeholder for the new asset and add it to the album editing request. PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset]; [albumChangeRequest addAssets:@[ placeHolder ]]; NSLog(@"%@",placeHolder.localIdentifier); if (placeHolder) { onSuccess(placeHolder.localIdentifier); } } completionHandler:^(BOOL success, NSError *error) { NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); if (error) { onError(error); } }]; }
这是我用来检索这张照片的代码:
PHImageManager *imgManager = [[PHImageManager alloc] init]; PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[_imageLocalIdentifier] options:nil]; if([fetchResult count] > 0) { PHAsset *asset = [fetchResult objectAtIndex:0]; PHImageRequestOptions *option = [PHImageRequestOptions new]; option.synchronous = NO; option.version = PHImageRequestOptionsVersionCurrent; option.networkAccessAllowed = YES; option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; option.resizeMode = PHImageRequestOptionsResizeModeFast; [imgManager requestImageForAsset:asset targetSize:CGSizeMake(CAMERA_GALLERY_SIZE, CAMERA_GALLERY_SIZE) contentMode:PHImageContentModeDefault options:option resultHandler:^(UIImage *result, NSDictionary *info) { [cell.photoIV setImage:result]; }]; }
使用这段代码,在存储的12张照片的样本中(他们在我的专辑中可以正常)4或5个本地标识符返回空的获取结果。 这是在iOS 8,iOS 9和iOS 10中测试的(iOS 10确实更糟糕,因为几乎所有的获取结果都是空的)。
我已经读到类似于此的东西是以前版本的iOS中的一个错误,但我想这不是现在的原因。
我尝试过这种方法来检索照片:
- (PHAsset *)getAssetFromGallery:(NSString *)identifier { PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[identifier] options:nil].lastObject; if(asset != nil) return asset; __block PHAsset *result; PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init]; [fetchOptions setPredicate:[NSPredicate predicateWithFormat:@"localIdentifier == %@", identifier]]; [userAlbums enumerateObjectsUsingBlock:^(id _Nonnull objectCollection, NSUInteger idx, BOOL * _Nonnull stopCollectionEnumeration) { PHAssetCollection *collection = nil; if(![objectCollection isKindOfClass:[PHAssetCollection class]]) return; collection = (PHAssetCollection *)objectCollection; PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; [assetsFetchResult enumerateObjectsUsingBlock:^(id _Nonnull objectAsset, NSUInteger idx, BOOL * _Nonnull stopAssetEnumeration) { PHAsset *asset = nil; if(![objectAsset isKindOfClass:[PHAsset class]]) return; result = asset; *stopAssetEnumeration = YES; *stopCollectionEnumeration = YES; }]; }]; return asset; }
我已尝试使用
PHAssetCollectionSubtypeAlbumMyPhotoStream
而不是PHAssetCollectionSubtypeAny
。 我尝试使用@"localIdentifier ==[cd] %@"
而不是@"localIdentifier == %@".
并且总是相同的结果,很多时候获取结果都是空的。 知道它发生了什么?I'm using
Photos.Framework
to save photos taken from the camera into my gallery and to retrieve them.This is the code I'm using to store the photos:
__block PHAssetCollection *album = [self getMyAlbumWithName:@"MyAlbumName"]; if(album == nil) { [self makeAlbumWithTitle:@"MyAlbumName" onSuccess:^(NSString *AlbumId) { album = [self getMyAlbumWithName:@"MyAlbumName"]; [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) { _imageLocalIdentifier = imageId; } onError:^(NSError *error) { // No need to do anything }]; } onError:^(NSError *error) { // No need to do anything }]; } else { [self addNewAssetWithImage:_imageToStore toAlbum:album onSuccess:^(NSString *ImageId) { _imageLocalIdentifier = imageId; } onError:^(NSError *error) { // No need to do anything }]; } -(PHAssetCollection *)getMyAlbumWithName:(NSString*)AlbumName { PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; NSLog(@"assetCollections.count = %lu", assetCollections.count); if (assetCollections.count == 0) return nil; __block PHAssetCollection * myAlbum; [assetCollections enumerateObjectsUsingBlock:^(PHAssetCollection *album, NSUInteger idx, BOOL *stop) { NSLog(@"album:%@", album); NSLog(@"album.localizedTitle:%@", album.localizedTitle); if ([album.localizedTitle isEqualToString:AlbumName]) { myAlbum = album; *stop = YES; } }]; if (!myAlbum) return nil; return myAlbum; } -(void)makeAlbumWithTitle:(NSString *)title onSuccess:(void(^)(NSString *AlbumId))onSuccess onError: (void(^)(NSError * error)) onError { //Check weather the album already exist or not if (![self getMyAlbumWithName:title]) { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // Request editing the album. PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title]; // Get a placeholder for the new asset and add it to the album editing request. PHObjectPlaceholder * placeHolder = [createAlbumRequest placeholderForCreatedAssetCollection]; if (placeHolder) { onSuccess(placeHolder.localIdentifier); } } completionHandler:^(BOOL success, NSError *error) { NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); if (error) { onError(error); } }]; } } -(void)addNewAssetWithImage:(UIImage *)image toAlbum:(PHAssetCollection *)album onSuccess:(void(^)(NSString *ImageId))onSuccess onError: (void(^)(NSError * error)) onError { [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ // Request creating an asset from the image. PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; // Request editing the album. PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album]; // Get a placeholder for the new asset and add it to the album editing request. PHObjectPlaceholder * placeHolder = [createAssetRequest placeholderForCreatedAsset]; [albumChangeRequest addAssets:@[ placeHolder ]]; NSLog(@"%@",placeHolder.localIdentifier); if (placeHolder) { onSuccess(placeHolder.localIdentifier); } } completionHandler:^(BOOL success, NSError *error) { NSLog(@"Finished adding asset. %@", (success ? @"Success" : error)); if (error) { onError(error); } }]; }
And this is the code I'm using to retrieve this photo:
PHImageManager *imgManager = [[PHImageManager alloc] init]; PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[_imageLocalIdentifier] options:nil]; if([fetchResult count] > 0) { PHAsset *asset = [fetchResult objectAtIndex:0]; PHImageRequestOptions *option = [PHImageRequestOptions new]; option.synchronous = NO; option.version = PHImageRequestOptionsVersionCurrent; option.networkAccessAllowed = YES; option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic; option.resizeMode = PHImageRequestOptionsResizeModeFast; [imgManager requestImageForAsset:asset targetSize:CGSizeMake(CAMERA_GALLERY_SIZE, CAMERA_GALLERY_SIZE) contentMode:PHImageContentModeDefault options:option resultHandler:^(UIImage *result, NSDictionary *info) { [cell.photoIV setImage:result]; }]; }
With this piece of code, over a sample of 12 photos stored (they are ok in my album) 4 or 5 of their localidentifiers returns an empty fetch results. This is tested in iOS 8, iOS 9 and iOS 10 (with iOS 10 it's indeed worse because almost all of the fetch results are empty).
I've read that something similar to this was a bug in previous versions of iOS, but I guess this is not the reason now.
I've tried with this method to retrieve the photos:
- (PHAsset *)getAssetFromGallery:(NSString *)identifier { PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[identifier] options:nil].lastObject; if(asset != nil) return asset; __block PHAsset *result; PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init]; [fetchOptions setPredicate:[NSPredicate predicateWithFormat:@"localIdentifier == %@", identifier]]; [userAlbums enumerateObjectsUsingBlock:^(id _Nonnull objectCollection, NSUInteger idx, BOOL * _Nonnull stopCollectionEnumeration) { PHAssetCollection *collection = nil; if(![objectCollection isKindOfClass:[PHAssetCollection class]]) return; collection = (PHAssetCollection *)objectCollection; PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions]; [assetsFetchResult enumerateObjectsUsingBlock:^(id _Nonnull objectAsset, NSUInteger idx, BOOL * _Nonnull stopAssetEnumeration) { PHAsset *asset = nil; if(![objectAsset isKindOfClass:[PHAsset class]]) return; result = asset; *stopAssetEnumeration = YES; *stopCollectionEnumeration = YES; }]; }]; return asset; }
I've tried with
PHAssetCollectionSubtypeAlbumMyPhotoStream
instead ofPHAssetCollectionSubtypeAny
. And I've tried with@"localIdentifier ==[cd] %@"
instead of@"localIdentifier == %@".
And always the same results, lots of times the fetch results is empty. Any idea of what is it happening?
原文:https://stackoverflow.com/questions/39549226
最满意答案
如果你想要不区分大小写的过滤(例如
"Jones"
,"jOnes"
应匹配)List<User> FilteredUsers = AllUsers .Where(user => user.Surname.IndexOf("jones", StringComparison.OrdinalIgnoreCase) >= 0)) .ToList();
As haim770 stated it was a case sensitivity issue! Such a simple mistake! Thank you.
相关问答
更多-
通过另一个列表
C#LINQ过滤列表 [2022-06-02]您可以在lUser列表上使用LINQ Any方法,如下所示: var coupons = lCoupon .Where(c => lUser.Any(u => u.selected && u.name == c.username)) .ToList(); You could use the LINQ Any method on the lUser list, as in: var coupons = lCoupon .Where(c => lUser.Any(u => u.sele ... -
所以我最终得到它的工作得益于设拉子给出的指针。 DataLoadOptions options = new DataLoadOptions(); options.AssociateWith
(item => item.VerseTranslation.Where(t => languageId.Contains(t.LanguageId))); dc.LoadOptions = options; var res = from s ... -
如果你需要使用Linq,你可以使用SPMetal 。 但是通过使用CAML查询可以获得更好的性能,如下所示: SPWeb web = SPContext.Current.Web; SPList list = web.Lists[LISTNAME]; SPQuery query = new SPQuery { Query = @"
... -
如果你想要不区分大小写的过滤(例如"Jones" , "jOnes"应匹配) List
FilteredUsers = AllUsers .Where(user => user.Surname.IndexOf("jones", StringComparison.OrdinalIgnoreCase) >= 0)) .ToList(); As haim770 stated it was a case sensitivity issue! Such a simple mi ... -
您可以尝试使用这些产品获取其status为真的类别 var newCategories = categories.Select( i => new Category { Id = i.Id, Status = i.Status, Products = i.Pr ...
-
你可以使用Where + Intersect + Any : var query = activities .Where(a => a.Categories.Select(c => c.CategoryId).Intersect(yourIdList).Any()); 另一种(效率较低)方式是使用Enumerable.Any + Contains : var query = activities .Where(a => a.Categories.Any(c => yourIdList.Con ...
-
你可以为此使用OfType
。 var results = c.OfType (); 这个 Console.WriteLine (c.OfType ().Count()); 结果是 2 作为旁注: .Select()不会选择任何内容。 那么,它的确如此:它“选择”每个元素并将其投影到一个新对象。 但它不会在某些标准上选择对象。 对于值,类型选择有.Where()和同样选择器和.OfType 。 You can use OfType for this. var ... -
这听起来像你想要的东西一样: var newList = objList.Select(x => x.date1.Date) .Concat(objList.Select(x => x.date2.Date)) .Distinct() .ToList(); 这看起来对你有好处吗? It sounds like you want something like: var newList ...
-
FullSupplierList.Where(s => s.Products.Any(p => p.Category.Name == "Green")) .ToList(); FullSupplierList.Where(s => s.Products.Any(p => p.Category.Name == "Green")) .ToList();
-
类对象列表 - 使用LINQ过滤具有相同值的类对象(List of class objects - Filter class objects with same values using LINQ)[2022-01-02]
您需要定义两种方法: private IEnumerableGetPlayersSuccessfullInAttempt(IEnumerable players, int attempt) { return players.Where(p=>p.sPlayerSuccess = "YES" && p.iAttemptId == attempt) .Select(p => p.sPlayerId); } private IEnumerable ...