Here are the steps that we perform in order to replace photo in the main Camera Roll collection:
1. We get PHAssetCollection collection:
func fetchAssetCollectionForAllPhotos() -> PHAssetCollection! {
let collection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)
if let first = collection.firstObject {
return first
}
return nil
}
https://w3tls.net/ROf32e581d976c21db38fcc236b7afa257c791.png
2. In order to replace photo we find index of the photo:
func searchImageIndex(identifier: String) -> Int? {
let fetchResult = PHAsset.fetchAssets(in: self.fetchAssetCollectionForAllPhotos(), options: nil) as! PHFetchResult<AnyObject>
for assetIndex in 0..<fetchResult.count {
if let item = fetchResult.object(at: assetIndex) as? PHAsset, item.localIdentifier == identifier {
return assetIndex
}
}
return nil
}
https://w3tls.net/ROf32e5e156dd58ccffcebb161d68dc27e8cbe.png
3. Replace photo:
func replacePhoto(identifier: String, onImage image: UIImage, complate:@escaping (String)->()) throws {
guard let index = searchImageIndex(identifier: identifier) else { throw MediaManagerError.errorReplace }
try PHPhotoLibrary.shared().performChangesAndWait {
let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset!
let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.fetchAssetCollectionForAllPhotos())
albumChangeRequest!.replaceAssets(at: [index], withAssets: [assetPlaceholder] as NSArray)
complate(assetPlaceholder.localIdentifier)
}
}
https://w3tls.net/ROf32e5ff2649b2d721f90ade374273219cdad.png
As a result, in the main collection Camera Roll photo is duplicated, and if you change it in the custom collection, the photo changes without duplication.