select一张图片导致重新保存到相机胶卷

我有一个程序,用户select一张照片放在屏幕上,代码自动将其放入自定义相册中。 但是,每当他们select一张照片,它将其重新保存到相机胶卷,创build重复。 我如何让它停止这样做?

func fetchAssetCollectionForAlbum() -> PHAssetCollection? { let fetchOptions = PHFetchOptions() fetchOptions.predicate = NSPredicate(format: "title = %@", albumName) // fetch the asset for the album let collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions) var picturePlaceHolder: PHObjectPlaceholder? = nil if let _: AnyObject = collection.firstObject { return collection.firstObject } return nil } func save(image: UIImage) { if assetCollection == nil { return } PHPhotoLibrary.shared().performChanges({ let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection) let enumeration: NSArray = [assetPlaceHolder!] albumChangeRequest!.addAssets(enumeration) }, completionHandler: nil) } 

我发布了一个类似的问题: Swift 3或4保存到自定义相册会创build重复的图像

但是除了蟋蟀,我什么都没有。 幸运的是,我想我find了答案。 我也会回答我自己的问题。

你有的代码(这是我有相同的代码)是创build一个新的资产。 只有在用户使用相机拍摄照片后才能将图像保存到自定义相册中。 这是为了全新的资产。

但是,对于现有资产,您不希望创build新的资产。 而是要将现有资产添加到自定义相册。 要做到这一点,你需要一个不同的方法。 这是我创build的代码,它似乎工作。 请记住,您必须先获取资产ID,以便将其发送到您的方法并访问现有资产。

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

 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类(或任何地方的任何function)中,编辑资源而不是创build一个新的,这就是我所拥有的。 我假设changeRequestvariables可以被省略。 我只是玩弄,直到我得到这个权利。 通过完全荒谬的苹果文件,我至less能够注意到还有其他方法可以使用。 我发现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); }) } } 

所以,它几乎是一样的,除了创build资产创build请求并为创build的资产生成占位符之外,您只需使用现有资产ID来获取现有资产并将现有资产添加到addasset / insertasset NSArray参数而不是新创build的资产占位符。