Swift 3或4保存到custum相册会创建重复的图像 [英] Swift 3 or 4 Saving to custum album creates duplicate images

查看:183
本文介绍了Swift 3或4保存到custum相册会创建重复的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am saving images to a custom album after either select or camera completion. Obviously, after camera completion, there is only one image, but when a user selects images in the gallery picker, in the completion handler, when I save that image to the custom album, a duplicate is ALWAYS created. Both in the gallery as well as the root photoAlbum. Everywhere, it seems. I cannot reference the ID to see if it was created before, because the ID is being newly created with the placeholder.

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

Is there a way to get the base image reference ID so that I can associate EVERY image to the original? As I understand it, IOS (I hate ios btw), saves only one actual image and the rest are just pointers to the original image object. If that is the case, I would expect there is a way to get a solid reference to the original Image and from there, I can easily manage assets created from that base image.

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


推荐答案

没有人愿意帮忙解决这个问题。幸运的是,我能够找到解决方案。对于任何遇到过这种情况的人或者同样坐在蟋蟀周围的人:选择图片会导致重新保存到相机胶卷这里是一个解决方案。

No one bothered to assist with this. Luckily, I was able to find the solution. For any who come across this or the similar one that was also sitting around with the crickets: Choosing a picture causes resave to camera roll here is a solution.

我的代码是创建一个新的资产。仅在用户使用相机拍摄照片后将图像保存到自定义相册时才有用。这是为了全新的资产。

The code I have is to CREATE A NEW ASSET. It is useful only for the saving the image to your custom album after the user has taken a picture with the camera. It is for brand new assets.

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

However, for existing assets, you do not want to create a new asset. Instead, you want to add the existing asset to the custom album. To do this, you need a different method. Here is the code I created and it seems to be working. Keep in mind that you will have to get the asset ID FIRST, so that you can send it to your method and access the existing asset.

因此,在您的imagePickerController中,您必须确定用户是否选择了现有图像,或者是否正在通过新的相机操作调用该方法。

So, in your imagePickerController, you have to determine whether the user chose an existing image or whether the method is being called from a new camera action.

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对象。

Now, in your photohelper class (or in any function anywhere, whatever), to EDIT the asset instead of create a new one, this is what I have. I am assuming the changeRequest variable can be ommitted. I was just playing around until I got this right. Going through the completely ridiculous apple docs I was able to at least notice that there were other methods to play with. I found that the NSFastEnumeration parameter can be an NSArray of PHAssets, and not just placeholder PHObjectPlaceholder objects.

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参数中而不是新创建的资产

So, it is pretty much the same, except instead of creating an Asset Creation Request and generating a placeholder for the created asset, you instead just use the existing asset ID to fetch an existing asset and add the existing asset to the addasset/insertasset NSArray parameter instead of a newly created asset

这篇关于Swift 3或4保存到custum相册会创建重复的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆