web-dev-qa-db-fra.com

Photos Framework requestImageDataForAsset échoue parfois

J'utilise le framework de photos sur iOS8.1 et demande les données d'image pour l'actif à l'aide de requestImageDataForAsset ... La plupart du temps, cela fonctionne et j'obtiens les données d'image et un dictionnaire contenant ce que vous voyez ci-dessous. Mais parfois, l'appel est terminé, mais les données sont nuls et le dictionnaire contient trois entrées génériques. 

Les appels sont effectués séquentiellement et sur le même thread. Ce n'est pas spécifique à une image particulière. L'erreur se produira sur les images que j'ai déjà ouvertes avec succès. Quelqu'un at-il rencontré cela?

+ (NSData *)retrieveAssetDataPhotosFramework:(NSURL *)urlMedia resolution:(CGFloat)resolution imageOrientation:(ALAssetOrientation*)imageOrientation {

    __block NSData *iData = nil;

    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[urlMedia] options:nil];
    PHAsset *asset = [result firstObject];

    PHImageManager *imageManager = [PHImageManager defaultManager];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    options.synchronous = YES;
    options.version = PHImageRequestOptionsVersionCurrent;

    @autoreleasepool {
        [imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
            iData = [imageData copy];
            NSLog(@"requestImageDataForAsset returned info(%@)", info);
            *imageOrientation = (ALAssetOrientation)orientation;
        }];
    }

    assert(iData.length != 0);
    return iData;
}

Voici le résultat souhaité où je récupère les données image et le dictionnaire de métadonnées:

requestImageDataForAsset returned info({
    PHImageFileDataKey = <PLXPCShMemData: 0x1702214a0> bufferLength=1753088 dataLength=1749524;
    PHImageFileOrientationKey = 1;
    PHImageFileSandboxExtensionTokenKey = "6e14948c4d0019fbb4d14cc5e021199f724f0323;00000000;00000000;000000000000001a;com.Apple.app-sandbox.read;00000001;01000003;000000000009da80;/private/var/mobile/Media/DCIM/107Apple/IMG_7258.JPG";
    PHImageFileURLKey = "file:///var/mobile/Media/DCIM/107Apple/IMG_7258.JPG";
    PHImageFileUTIKey = "public.jpeg";
    PHImageResultDeliveredImageFormatKey = 9999;
    PHImageResultIsDegradedKey = 0;
    PHImageResultIsInCloudKey = 0;
    PHImageResultIsPlaceholderKey = 0;
    PHImageResultWantedImageFormatKey = 9999;
})

Voici ce que je reçois de temps en temps. les données d'image sont nulles. Le dictionnaire ne contient pas tellement.

requestImageDataForAsset returned info({
    PHImageResultDeliveredImageFormatKey = 9999;
    PHImageResultIsDegradedKey = 0;
    PHImageResultWantedImageFormatKey = 9999;
})
20
Dan Loughney

Vous êtes probablement en train d'itérer à travers un tableau, et la mémoire n'est pas libérée à temps, vous pouvez essayer le code ci-dessous. Assurez-vous que theData est marqué par __block

@autoreleasepool {
    [imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
        NSLog(@"requestImageDataForAsset returned info(%@)", info);
        theData = [imageData copy];
    }];
}
2
gabbler

J'ai eu un problème avec des symptômes similaires où requestImageDataForAsset a renvoyé des données d'image nulles, mais était également accompagné d'un message d'erreur de la console du type suivant:

[Generic] Failed to load image data for asset <PHAsset: 0x13d041940> 87CCAFDC-A0E3-4AC9-AD1C-3F57B897A52E/L0/001 mediaType=1/0, sourceType=2, (113x124), creationDate=2015-06-29 04:56:34 +0000, location=0, hidden=0, favorite=0 with format 9999

Dans mon cas, le problème a soudainement commencé à se produire sur un périphérique spécifique uniquement avec des actifs dans des albums partagés iCloud après la mise à niveau d'iOS 10.x vers 11.0.3 et depuis lors jusqu'à 11.2.5. Pensant que requestImageDataForAsset essayait peut-être d'utiliser des fichiers localement mis en cache dans /var/mobile/Media/PhotoData/PhotoCloudSharingData/ (à partir de la clé PHImageFileURLKey du dictionnaire d'informations) et que le cache était peut-être corrompu, j'ai réfléchi à la façon de le vider.

Basculer le commutateur 'iCloud Photo Sharing' dans iOS ' Paramètres -> Comptes et mots de passe -> iCloud -> Photos semble avoir fait l'affaire. requestImageDataForAsset fonctionne maintenant pour les actifs précédemment défaillants.

Mise à jour du 9 mars 2018

Je peux reproduire ce problème maintenant. Cela semble se produire après la restauration d'une sauvegarde depuis iTunes: 

  1. Utilisez l'application iOS et récupérez des photos d'un album partagé iCloud. 
  2. Sauvegardez le périphérique iOS en utilisant iTunes.
  3. Restaurez la sauvegarde en utilisant iTunes.
  4. L'utilisation de l'application à nouveau pour récupérer les mêmes photos de l'album partagé iCloud échoue désormais avec le message de console ci-dessus.

Activer le commutateur 'iCloud Photo Sharing' résout le problème. Vraisemblablement, le processus de restauration corrompt en partie le cache. Je l'ai signalé comme bogue 38290463 à Apple.

4
user2067021

Revenant à cela après un long moment, j'ai résolu une grande partie de mon problème. Pas de mystère, juste un mauvais code:

PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[urlMedia] options:nil];
PHAsset *asset = [result firstObject];

if (asset != nil) { // the fix
    PHImageManager *imageManager = [PHImageManager defaultManager];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    ...
}

La cause la plus courante pour moi était un problème d'URL de média transmise à fetchAssetsWithALAssetURLs, l'actif étant alors nul et requestImageDataForAsset renvoyant un objet info par défaut.

0
Dan Loughney