Skip to content

Instantly share code, notes, and snippets.

Last active March 24, 2023 04:54
What would you like to do?
import UIKit
import MobileCoreServices
import ImageIO
let sourceOptions: [String: AnyObject] = [kCGImageSourceTypeIdentifierHint as String: kUTTypeJPEG]
let cfSourceOptions = sourceOptions as CFDictionary
let image = UIImage(named: "input.jpg")!
let data = UIImageJPEGRepresentation(image, 1.0)
let source: CGImageSource = CGImageSourceCreateWithData(data as! CFData, cfSourceOptions)!
let filepath = NSTemporaryDirectory().appending("out.jpg")
print("Output file:")
let fileURL: URL = URL(fileURLWithPath: filepath)
let destination: CGImageDestination = CGImageDestinationCreateWithURL(fileURL as CFURL, kUTTypeJPEG, 1, nil)!
var makeTag = CGImageMetadataTagCreate(
kCGImageMetadataNamespaceTIFF, kCGImageMetadataPrefixTIFF, kCGImagePropertyTIFFMake, .string, "Make" as CFString
var modelTag = CGImageMetadataTagCreate(
kCGImageMetadataNamespaceTIFF, kCGImageMetadataPrefixTIFF, kCGImagePropertyTIFFModel, .string, "Model" as CFString
var metaDatas = CGImageMetadataCreateMutable()
var tagPath = "tiff:Make" as CFString
var result = CGImageMetadataSetTagWithPath(metaDatas, nil, tagPath, makeTag)
tagPath = "tiff:Model" as CFString
result = CGImageMetadataSetTagWithPath(metaDatas, nil, tagPath, modelTag)
let destOptions: [String: AnyObject] = [
kCGImageDestinationMergeMetadata as String: NSNumber(value: 1),
kCGImageDestinationMetadata as String: metaDatas
let cfDestOptions = destOptions as CFDictionary
var error: Unmanaged<CFError>?
var errorPtr: UnsafeMutablePointer<CFError>
withUnsafeMutablePointer(to: &error, { ptr in
result = CGImageDestinationCopyImageSource(destination, source, cfDestOptions, ptr)
print(String(format: "Write image to file result: %@", result ? "Success" : "Failed"))
print(String(format: "With error: %@", error.debugDescription))
let writeResult = CGImageDestinationFinalize(destination)
// This is false, and you may see an error like:
// " ImageIO: finalize:2031: not allowed for image destination that was updated with CGImageDestinationCopyImageSource "
// But, in practice, it works. The file is there and the metadata is correct.
Copy link

@maurymarkowitz no idea about errorPtr I ended up not having that line in production. Thanks for the tips too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment