2017-09-30 2 views
0

J'enregistre des images dans un album personnalisé après la sélection ou l'achèvement de la caméra. Évidemment, après l'achèvement de la caméra, il n'y a qu'une seule image, mais lorsqu'un utilisateur sélectionne des images dans le sélecteur de galerie, dans le gestionnaire d'achèvement, lorsque je sauvegarde cette image dans l'album personnalisé, un double est TOUJOURS créé. Les deux dans la galerie ainsi que la photoAlbum racine. Partout, il semble. Je ne peux pas référencer l'ID pour voir s'il a été créé auparavant, car l'ID est en train d'être créé avec l'espace réservé.Swift 3 ou 4 L'enregistrement dans un album custum crée des images en double

Existe-t-il un moyen d'obtenir l'ID de référence d'image de base afin que je puisse associer CHAQUE image à l'original? Si je comprends bien, IOS (je déteste ios btw), enregistre seulement une image réelle et le reste ne sont que des pointeurs vers l'objet image d'origine. Si tel est le cas, je m'attendrais à ce qu'il y ait un moyen d'obtenir une référence solide à l'image originale et à partir de là, je puisse facilement gérer les ressources créées à partir de cette image de base.

public static func addNewImage(_ image:UIImage, toAlbum albumName:String,imageID:String?,onSuccess success:@escaping(String)->Void, onFailure failure:@escaping(Error?)->Void) { 
     guard let album = self.getAlbum(withName: albumName) else { 
      failure(SDPhotosHelper.albumNotFoundError) 
      return 
     } 

     var localIdentifier = String(); 

     if(imageID != nil){ 
      if(self.hasImageInAlbum(withIdentifier: imageID!, fromAlbum: albumName)){ 
       failure(SDPhotosHelper.albumNotFoundError) 
       return; 
       } 
     } 

     PHPhotoLibrary.shared().performChanges({ 
       let albumChangeRequest = PHAssetCollectionChangeRequest(for: album) 

      let assetCreationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) 
      //assetCreationRequest.location = ""; 
      let placeHolder = assetCreationRequest.placeholderForCreatedAsset 
      albumChangeRequest?.addAssets([placeHolder!] as NSArray) 
      if placeHolder != nil { 
       localIdentifier = (placeHolder?.localIdentifier)! 
      } 

     }) { (didSucceed, error) in 
      OperationQueue.main.addOperation({ 
       didSucceed ? success(localIdentifier) : failure(error) 
      }) 
     } 
    } 
+0

Ceci est très utile! J'ai eu une question similaire ici https://stackoverflow.com/questions/47378305/how-do-i-copy-an-image-from-the-iphone-photos-library-to-my-album-without-having? noredirect = 1 # comment81709017_47378305 –

Répondre

0

Personne ne s'est occupé de cela. Heureusement, j'ai été capable de trouver la solution. Pour tous ceux qui rencontrent ce ou celui qui était également assis avec les grillons: Choosing a picture causes resave to camera roll voici une solution.

Le code que j'ai est de créer un nouvel actif. Il est utile uniquement pour enregistrer l'image sur votre album personnalisé après que l'utilisateur a pris une photo avec l'appareil photo. C'est pour de nouveaux actifs. Toutefois, pour les actifs existants, vous ne souhaitez pas créer de nouvel actif. Au lieu de cela, vous voulez ajouter l'actif existant à l'album personnalisé. Pour ce faire, vous avez besoin d'une méthode différente. Voici le code que j'ai créé et il semble fonctionner. Gardez à l'esprit que vous devrez d'abord obtenir l'ID d'actif, afin de pouvoir l'envoyer à votre méthode et accéder à l'actif existant. Ainsi, dans votre imagePickerController, vous devez déterminer si l'utilisateur a choisi une image existante ou si la méthode est appelée à partir d'une nouvelle action de caméra.

let pickerSource = picker.sourceType; 
switch(pickerSource){ 
case .savedPhotosAlbum, .photoLibrary: 
    if(let url = info[UIIMagePickerControllerReferenceURL] as? NSURL{ 
    let refURLString = refURL?.absoluteString; 
    /* value for refURLString looks something like assets-library://asset/asset.JPG?id=82A6E75C-EA55-4C3A-A988-4BF8C7F3F8F5&ext=JPG */ 
    let refID = {function here to extract the id query param from the url string} 
    /*above gets you the asset ID, you can get the asset directly, but it is only 
    available in ios 11+. 
    */ 
    MYPHOTOHELPERCLASS.transferImage(toAlbum: "myalbumname", withID: refID!, ...) 

} 
break; 
case .camera: 
... 
break; 
} 

Maintenant, dans votre classe PhotoHelper (ou dans une fonction où, peu importe) pour éditer l'actif au lieu de créer un nouveau, c'est ce que j'ai. Je suppose que la variable changeRequest peut être omise. Je jouais juste jusqu'à ce que je comprenne bien. En passant par les docs de la pomme complètement ridicules, j'ai pu remarquer au moins qu'il y avait d'autres méthodes pour jouer avec. J'ai trouvé que le paramètre NSFastEnumeration peut être un NSArray de PHAssets, et pas seulement des objets PHObjectPlaceholder d'espace réservé.

public static func transferImage(toAlbum albumName:String, withID imageID:String, onSuccess success:@escaping(String)->Void, onFailure failure:@escaping(Error?)->Void){ 

    guard let album = self.getAlbum(withName: albumName) else{ 
    ... failure here, albumNotFoundError 
    return; 
    } 

    if(self.hasImageInAlbum(withIdentifier: imageID, fromAlbum: albunName)){ 
    ... failure here, image already exists in the album, do not make another 
    return; 
    } 

    let theAsset = self.getExistingAsset(withLocalIdentifier: imageID); 
    if(theAsset == nil){ 
    ... failure, no asset for asset id 
    return; 
    } 

    PHPhotoLibrary.shared().performChanges({ 
     let albumChangeRequest = PHAssetCollectionChangeRequest(for: album); 
     let changeRequest = PHAssetChangeRequest.init(for: theAsset!); 
     let enumeration:NSArray = [theAsset!]; 
     let cnt = album.estimatedAssetCount; 
     if(cnt == 0){ 
      albumChangeRequest?.addAssets(enumeration); 
     }else{ 
      albumChangeRequest?.inserAssets(enumeration, at: [0]); 
     } 
    }){didSucceed, error) in 
     OperationQueue.main.addOperation({ 
     didSucceed ? success(imageID) : failure(error); 
     }) 
    } 

} 

Ainsi, il est à peu près le même, sauf au lieu de créer une demande de création d'actifs et de générer un espace réservé pour l'actif créé, vous plutôt que d'utiliser l'ID actif existant pour récupérer un actif existant et ajouter l'actuel Actif dans le paramètre NSArray addasset/insertasset au lieu d'un actif nouvellement créé