J'utilise Photos.Framework
pour enregistrer les photos prises depuis l'appareil photo dans ma galerie et pour les récupérer.FetchAssetsWithLocalIdentifiers renvoie le tableau vide
C'est le code que je utilise pour stocker les 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);
}
}];
}
Et c'est le code que je utilise pour récupérer cette 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];
}];
}
Avec ce morceau de code , sur un échantillon de 12 photos stockées (elles sont correctes dans mon album) 4 ou 5 de leurs identifiants locaux renvoie un résultat de recherche vide. Cela a été testé sur iOS 8, iOS 9 et iOS 10 (avec iOS 10, c'est pire car presque tous les résultats de recherche sont vides).
J'ai lu que quelque chose de similaire à ceci était un bug dans les versions précédentes d'iOS, mais je suppose que ce n'est pas la raison maintenant.
J'ai essayé avec cette méthode pour récupérer les 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;
}
J'ai essayé avec PHAssetCollectionSubtypeAlbumMyPhotoStream
au lieu de PHAssetCollectionSubtypeAny
. Et j'ai essayé avec @"localIdentifier ==[cd] %@"
au lieu de @"localIdentifier == %@".
Et toujours les mêmes résultats, beaucoup de fois les résultats d'extraction sont vides. Une idée de ce qui se passe?
Avez-vous trouvé la veille cause de cela? Même chose pour moi – StackOverflower
Oui, la raison était que j'appelais onSuccess (placeHolder.localIdentifier); à l'intérieur du bloc performChanges au lieu de l'intérieur du bloc completionHandler. Je vais répondre à ma propre question avec ma mise à jour de code afin que vous puissiez le vérifier. – Wonton
Merci de répondre, je vais vérifier votre réponse :) – StackOverflower