Edición de metadatos de fotos y PHAdjustmentData

La siguiente función carga una foto, edita los metadatos exif adjuntos y la vuelve a guardar. La función solo parece funcionar para fotos que ya tienen un PHAdjustmentData adjunto, es decir, fotos que se han editado con otra aplicación anteriormente. Si una foto no ha sido editada, falla en el bloque performChanges () e imprime

Failed to save. Error: Optional(Error Domain=NSCocoaErrorDomain Code=-1 "(null)"). 

¿Por qué falla en esta situación? Mirando a través de Stack Overflow, he visto varias otras versiones de esta pregunta, pero ninguna de ellas pareció resolverse. Sé que esto falla si la imagen guardada es un PNG pero mi imagen original es un JPEG, por lo que la imagen guardada también es un JPEG.

func editPhotoProperties(_ asset: PHAsset) {

    let options = PHContentEditingInputRequestOptions()
    options.canHandleAdjustmentData = { data in
            return false
    }
    asset.requestContentEditingInput(with: options) { input, info in
        if let input = input {
            let adjustmentData = PHAdjustmentData(formatIdentifier:"viewfinder", formatVersion:"1.0", data:"viewfinder".data(using:.utf8)!)
            let output = PHContentEditingOutput(contentEditingInput:input)
            output.adjustmentData = adjustmentData

            do {
                let imageData = try Data(contentsOf:input.fullSizeImageURL!)
            } catch {
                print("Failed to load data")
                return
            }

            let properties = getImageDataProperties(imageData)!
            let properties2 = properties.mutableCopy() as! NSMutableDictionary
            // edit properties2
            ...
            let newImageData = addImageProperties(imageData: imageData, properties: properties2)

            do {
                try newImageData!.write(to: output.renderedContentURL, options: .atomic)
            } catch {
                print("Failed to write to disk")
                return
            }           
            PHPhotoLibrary.shared().performChanges({
                let changeRequest = PHAssetChangeRequest(for:asset)
                changeRequest.contentEditingOutput = output
            }) { success, error in
                if !success {
                    print("Failed to save. Error: \(String(describing:error))")
                }
            }
        }
    }
}

func getImageDataProperties(_ data: Data) -> NSDictionary? {
    if let imageSource = CGImageSourceCreateWithData(data as CFData, nil) {
        if let dictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) {
            return dictionary
        }
    }
    return nil
}

// add image properties (exif, gps etc) to image
func addImageProperties(imageData: Data, properties: NSDictionary?) -> Data? {

    // create an imagesourceref
    if let source = CGImageSourceCreateWithData(imageData as CFData, nil) {
        // this is of type image
        if let uti = CGImageSourceGetType(source) {

            // create a new data object and write the new image into it
            let destinationData = NSMutableData()
            if let destination = CGImageDestinationCreateWithData(destinationData, uti, 1, nil) {

                // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
                CGImageDestinationAddImageFromSource(destination, source, 0, properties)
                if CGImageDestinationFinalize(destination) == false {
                    return nil
                }
                return destinationData as Data
            }
        }
    }
    return nil
}

Respuestas a la pregunta(0)

Su respuesta a la pregunta