web-dev-qa-db-fra.com

ALAssetsLibrary assetForURL: toujours renvoyer zéro pour les photos dans "My Photo Stream" dans iOS 8.1

Ce code fonctionnait bien dans iOS 7, mais dans iOS 8.1, tous les éléments situés dans l'album "My Photo Stream" sont nuls dans le bloc de résultats. (Le failBlock n'est pas appelé.) Les albums réguliers et les albums partagés fonctionnent très bien.

J'ai essayé la réponse acceptée de: Erreur lors de l'attribution de __block ALAsset à l'intérieur de assetForURL: resultBlock:

Autrement dit, je détiens une référence à un objet ALAssetsLibrary, à l'écoute de l'événement ALAssetsLibraryChangedNotification (qui ne se produit pas entre-temps, mais eh bien.) Je me suis assuré que mon application était autorisée à accéder aux photos, je ' m sur le wi-fi, je vois très bien les vignettes des photos dans ma tableView. C'est juste quand j'essaye de les charger avec assetForURL: ils sont toujours nuls.

// example URL: assets-library://asset/asset.JPG?id=1ECB69B9-DC7A-45A7-B135-F43317D3412C&ext=JPG
[self.library assetForURL:[NSURL URLWithString:url] resultBlock:^(ALAsset *asset) {
    NSLog(@"Asset: %@", asset); // nil :(
} failureBlock:^(NSError *error) {
    NSLog(@"Failure, wahhh!");
}];

Quelqu'un d'autre voit-il ce problème?

25
taber

J'ai eu le même problème. Passer au framework Photos n'est pas une option pour moi en ce moment, mais heureusement, j'ai trouvé une solution de contournement. Vous pouvez le trouver un peu moche et je soupçonne que cela peut fonctionner lentement lorsque Photo Stream contient beaucoup de photos, mais c'est mieux que rien.

L'idée est d'énumérer tous les éléments du groupe d'actifs Flux de photos et de comparer l'URL nécessaire avec l'URL de chaque élément. Heureusement, cela fonctionne toujours.

J'ai une méthode comme celle-ci (la bibliothèque est la propriété ALAssetsLibrary de la même classe, vous devrez peut-être l'initialiser dans ce code):

- (void)loadItem:(NSURL *)url withSuccessBlock:(void (^)(void))successBlock andFailureBlock:(void (^)(void))failureBlock {

[library assetForURL:url
        resultBlock:^(ALAsset *asset)
        {
            if (asset){
                //////////////////////////////////////////////////////
                // SUCCESS POINT #1 - asset is what we are looking for 
                //////////////////////////////////////////////////////
                successBlock();
            }
            else {
                // On iOS 8.1 [library assetForUrl] Photo Streams always returns nil. Try to obtain it in an alternative way

                [library enumerateGroupsWithTypes:ALAssetsGroupPhotoStream
                                       usingBlock:^(ALAssetsGroup *group, BOOL *stop)
                 {
                     [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                         if([result.defaultRepresentation.url isEqual:url])
                         {
                             ///////////////////////////////////////////////////////
                             // SUCCESS POINT #2 - result is what we are looking for
                             ///////////////////////////////////////////////////////
                             successBlock();
                             *stop = YES;
                         }
                     }];
                 }

                                     failureBlock:^(NSError *error)
                 {
                     NSLog(@"Error: Cannot load asset from photo stream - %@", [error localizedDescription]);
                     failureBlock();

                 }];
            }

        }
        failureBlock:^(NSError *error)
        {
            NSLog(@"Error: Cannot load asset - %@", [error localizedDescription]);
            failureBlock();
        }
  ];
}

J'espère que cela t'aides.

30
Andrew Simontsev

Depuis iOS 8.0 et versions ultérieures, Apple suggère d'utiliser le cadre Photos au lieu du cadre de la bibliothèque des actifs.

enter image description here

2
Ratan

J'ai fait l'observation qu'essayer de récupérer un actif en utilisant assetForURL à l'intérieur d'un bloc de succès writeImage toSavedPhotosAlbum pour ce même actif donnera un actif nul (la plupart du temps).

Cependant, la récupération de l'actif avec assetForURL quelque temps après l'exécution réussie du bloc writeImage aboutit à l'actif correct.

L'attente d'une seconde a fonctionné, tandis que l'attente de seulement 300 ms n'a pas fonctionné. Mais cela sera bien sûr différent pour chaque appareil et chaque situation.

Cela ne répond pas vraiment à la question de manière satisfaisante, mais peut-être que cela aide quelqu'un d'autre à comprendre le problème sous-jacent.

2
Thomas Hilbert

Testé avec l'iPad mini sur iOS 8.1, voici comment vous devez le faire avec le nouveau Photos Framework :

NSURL *url = /* your asset url from the old ALAsset library prior to iOS 8 */
PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsWithALAssetURLs:@[url]
                                                               options:nil];
assert(assets.count == 1);
PHAsset *asset = assets.firstObject;

[[PHImageManager defaultManager] requestImageForAsset:asset
                   targetSize:CGSizeMake(800, 800) // TODO: your target size
                  contentMode:PHImageContentModeDefault
                      options:nil
                resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info)
 {
     // Do whatever you want to the result
 }];
1
Yuchen Zhong