I'm trying to apply a transform edit to photos that a user selects from their photo library. I have the following code:
let options = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = { adjustmentData -> Bool in
adjustmentData.formatIdentifier == AdjustmentFormatIdentifier && adjustmentData.formatVersion == "1.0"
}
PHPhotoLibrary.shared().performChanges({
for asset in imageAssets {
asset!.requestContentEditingInput(with: options) {contentEditingInput, info in
// Create a CIImage from the full image representation
let url = contentEditingInput!.fullSizeImageURL!
let orientation = contentEditingInput!.fullSizeImageOrientation
var inputImage = CIImage(contentsOf: url, options: nil)!
inputImage = inputImage.oriented(forExifOrientation: orientation)
// Create the filter to apply
let transformFilter = CIFilter.lanczosScaleTransform()
transformFilter.inputImage = inputImage
transformFilter.scale = 1
transformFilter.aspectRatio = Float(stretchFactor)
// Apply the filter
let outputImage = transformFilter.outputImage
// Create a PHAdjustmentData object that describes the filter that was applied
let filterData = withUnsafeBytes(of: stretchFactor) { Data($0) }
let adjustmentData = PHAdjustmentData(formatIdentifier: AdjustmentFormatIdentifier, formatVersion: "1.0", data: filterData)
// Create a PHContentEditingOutput object and write a JPEG representation of the filtered object to the renderedContentURL
let contentEditingOutput = PHContentEditingOutput(contentEditingInput: contentEditingInput!)
let jpegData = UIImage(ciImage: outputImage!, scale: displayScale, orientation: .up).jpegData(compressionQuality: 1)
do {
try jpegData?.write(to: contentEditingOutput.renderedContentURL, options: .atomic)
} catch { }
contentEditingOutput.adjustmentData = adjustmentData
let request = PHAssetChangeRequest(for: asset!)
request.contentEditingOutput = contentEditingOutput
}
}
}, completionHandler: {success, error in
if success {
isPresented = false
}
})
But when I try to save the edits, I get an error stating This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:]
If I move the PHAssetChangeRequest()
line out of the requestContentEditingInput()
function and directly into PHPhotoLibrary.shared().performChanges({})
then it works, but the issue is that iOS displays a separate permission alert to allow saving the edited photo for every single photo the user selected (i.e. they have to tap "Allow" 10 times in a row). Instead, I only want to show a single permission alert asking "Do you want to allow this app to modify 10 photos?". This is definitely possible as apps like Pixelmator Photo do exactly this. How is it done?