Swift 3 或 4 保存到自定义相册会创建重复的图像

Posted

技术标签:

【中文标题】Swift 3 或 4 保存到自定义相册会创建重复的图像【英文标题】:Swift 3 or 4 Saving to custum album creates duplicate images 【发布时间】:2017-09-30 23:49:31 【问题描述】:

在选择或相机完成后,我将图像保存到自定义相册。显然,在相机完成后,只有一个图像,但是当用户在图库选择器中选择图像时,在完成处理程序中,当我将该图像保存到自定义相册时,总是会创建一个副本。在图库和根 photoAlbum 中。似乎无处不在。我无法引用 ID 来查看它是否是之前创建的,因为 ID 是使用占位符新创建的。

有没有办法获取基本图像参考 ID,以便我可以将每个图像与原始图像相关联?据我了解,ios(我讨厌 ios 顺便说一句)只保存一个实际图像,其余的只是指向原始图像对象的指针。如果是这种情况,我希望有一种方法可以获得对原始图像的可靠引用,并且我可以从那里轻松管理从该基础图像创建的资产。

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)
            )
        
    

【问题讨论】:

这太有用了!我在这里有一个类似的问题***.com/questions/47378305/… 【参考方案1】:

没有人愿意为此提供帮助。幸运的是,我能够找到解决方案。对于遇到此问题或与蟋蟀坐在一起的类似问题的任何人:Choosing a picture causes resave to camera roll 这是一个解决方案。

我拥有的代码是创建一个新资产。它仅用于在用户使用相机拍照后将图像保存到您的自定义相册。它适用于全新的资产。

但是,对于现有资产,您不想创建新资产。相反,您希望将现有资产添加到自定义相册。为此,您需要一种不同的方法。这是我创建的代码,它似乎正在工作。请记住,您必须首先获取资产 ID,以便您可以将其发送到您的方法并访问现有资产。

因此,在您的 imagePickerController 中,您必须确定用户是选择了现有图像还是从新的相机动作中调用了该方法。

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;

现在,在您的 photohelper 类中(或在任何地方的任何函数中),编辑资产而不是创建新资产,这就是我所拥有的。我假设 changeRequest 变量可以省略。我只是在玩,直到我做对了。通过完全荒谬的苹果文档,我至少能够注意到还有其他方法可以使用。我发现 NSFastEnumeration 参数可以是 PHAssets 的 NSArray,而不仅仅是占位符 PHObjectPlaceholder 对象。

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);
       )
    


因此,它几乎相同,除了创建资产创建请求并为创建的资产生成占位符之外,您只需使用现有资产 ID 获取现有资产并将现有资产添加到 addasset /insertasset NSArray 参数而不是新创建的资产

【讨论】:

以上是关于Swift 3 或 4 保存到自定义相册会创建重复的图像的主要内容,如果未能解决你的问题,请参考以下文章

Swift:将照片添加到自定义相册

如何将图像保存到自定义相册?

Phonegap(cordova)将图像保存到自定义相册

将视频保存到自定义相册 iOS

如何将图像保存到自定义相册?

将屏幕截图保存到自定义相册