2009-09-17 5 views
1

J'écris une application simple pour un artiste qui veut commercialiser son travail sur iTunes. Comme il n'y a que douze images, qui peuvent être supprimées plus rapidement qu'elles ne peuvent être sélectionnées à partir d'un sélecteur d'images, l'utilisateur ne sélectionne pas les images individuellement. Au lieu de cela, les images sont copiées par programme à partir de l'ensemble d'applications dans la photothèque. Cela minimise la taille et la complexité de l'application et évite à l'utilisateur final de devoir choisir chaque image individuellement.Comment forcer UIImageWriteToSavedPhotosAlbum à synchroniser (vider) les tampons?

Remarque: ce problème se produit uniquement sur le périphérique physique (iPhone 3Gs/3.1). Il n'est pas surprenant que mon implémentation implique d'appeler UIImageWriteToSavedPhotosAlbum à l'intérieur d'une boucle qui itère sur un tableau de 12 chemins complets vers les fichiers image correspondants (tous sont des fichiers JPEG). Moins les détails (par exemple, la vérification des erreurs, l'enregistrement, les paramètres de rappel en option), la boucle se résume à:

for (NSString* path in paths) { 
    image = [UIImage imageWithContentsOfFile:path]; 
    if (image) { 
     [NSThread sleepForTimeInterval:1.0]; // unacceptable 
     UIImageWriteToSavedPhotosAlbum(image, ...); 
    } 
} 

Notez la ligne marquée « inacceptable ». Pourquoi le thread actuel doit-il dormir une seconde avant chaque invocation de UIImageWriteToSavedPhotosAlbum (image, ...)? Eh bien, parce que c'est littéralement combien de temps cela prend pour iPhoneOS 3.1 (fonctionnant sur mon appareil 3Gs) de se débrouiller pour écrire réellement un objet UIImage tamponné au magasin persistant qui représente la photothèque de l'utilisateur! Comment je le sais? Eh bien, parce que sans l'appel à NSThread sleepForTimeInterval :, aucune erreur d'aucune sorte n'est jamais rapportée même si seulement une fraction des 12 images (qui semble varier aléatoirement entre 1 et 9) sont en fait copiées dans la photothèque. En outre, les résultats s'améliorent à mesure que l'intervalle de sommeil augmente, mais, comme je l'ai découvert, l'intervalle doit être considérablement augmenté avant que l'amélioration ne devienne perceptible. Même avec une valeur aussi élevée que 0,8 secondes, j'ai observé des fichiers manquants après des essais répétés. Au bout d'une seconde, j'ai observé jusqu'à trois "bonnes" opérations consécutives dans lesquelles tous les fichiers sont entièrement transférés avant de perdre toute patience. Je ai googlé ce problème à la mort, vérifié chaque publication sur ce forum qui mentionne UIImageWriteToSavedPhotosAlbum, et n'a rien trouvé. Suis-je la seule personne au monde qui ait jamais appelé cette fonction dans une boucle? Y a-t-il une raison pour laquelle il devrait être évident pour moi que je ne devrais pas le faire?

Répondre

-1

Une recherche rapide des forums de développeurs chez Apple tourné le poste suivant:

https://devforums.apple.com/message/112119#112119 pour le fil complet.

Ce thread me suggère qu'il n'y a aucun moyen sûr d'écrire une image à la photothèque par programme.

1

Face au même problème, j'ai trouvé un moyen de contourner le problème. Lorsque vous appelez UIImageWriteToSavedPhotosAlbum, vous pouvez passer le sélecteur de fin comme argument.
Ainsi, pas besoin d'appeler UIImageWriteToSavedPhotosAlbum dans une boucle. Lorsque la première invocation a complètement terminé sa sauvegarde (votre méthode d'achèvement est appelée), continuez. Utilisez un compteur pour contrôler le processus.

Voici mon code:

-(IBAction) SaveAllPictures { 
      UIImage *the_image; 
      if (images_to_photos_album < numberOfPhotos) { 
       the_image= [UIImage //get your image here] 
       UIImageWriteToSavedPhotosAlbum(the_image, self, @selector(imageSaved: error: context:), the_image); 
      } 

      if (images_to_photos_album == numberOfPhotos) { 
       the_image= [UIImage //get your image here 
       UIImageWriteToSavedPhotosAlbum(the_image, self, @selector(image: didFinishSavingWithError: contextInfo:), the_image); 
      } 


     } 


    -(void) imageSaved: (UIImage *) image error:(NSError *) error context: (void *) contextInfo { 

     NSLog(@"image saved, error = %@",error); 
     if (!error) { 
      images_to_photos_album = images_to_photos_album+1; 
      [self SaveAllPictures]; 
     } else { 
      //handle error here 
     } 

    } 


- (void) image: (UIImage *)image didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo { 


    images_to_photos_album =0; 

    if (error) { 
     // handle error here 
    } else { 
       // handle success here 
    } 

} 
Questions connexes