title: ImageIO: makerApple description: readMetadata and writeImage now expose the Apple Maker Note as makerApple, whose key '17' holds the Live Photo asset identifier.


Low-level image container I/O: read EXIF / GPS / TIFF / IPTC metadata, and encode images to formats (and with embedded metadata) that UIImage.toPNGData / toJPEGData can't produce.

Why not just use UIImage? A UIImage is a decoded bitmap — by the time you have one, the original file's metadata (EXIF, GPS, ...) is already gone, and toPNGData / toJPEGData cannot write HEIC / TIFF / GIF. ImageIO works at the encoded-container level, so it can both read existing metadata and write it back.

// Read metadata
const meta = await ImageIO.readMetadata("/path/to/photo.jpg")
console.log(meta.pixelWidth, meta.pixelHeight)
console.log(meta.gps?.Latitude, meta.gps?.Longitude)

// Re-encode a UIImage to HEIC with GPS
await ImageIO.writeImage({
  image,                       // a UIImage
  to: "/path/to/out.heic",
  format: "heic",
  quality: 0.9,
  metadata: {
    gps: { Latitude: 37.33, LatitudeRef: "N", Longitude: 122.0, LongitudeRef: "W" },
  },
})

ImageIO.readMetadata(source)

function readMetadata(source: string | Data): Promise<ImageMetadata>

Reads container-level metadata from a file path or Data. Rejects if the source can't be decoded as an image.

type ImageMetadata = {
  pixelWidth?: number
  pixelHeight?: number
  dpiWidth?: number
  dpiHeight?: number
  depth?: number
  colorModel?: string
  orientation?: number        // EXIF orientation 1–8
  hasAlpha?: boolean
  profileName?: string
  exif?: Record<string, any>  // CGImageProperties Exif keys, e.g. DateTimeOriginal
  gps?: Record<string, any>   // GPS keys, e.g. Latitude / Longitude / LatitudeRef
  tiff?: Record<string, any>
  iptc?: Record<string, any>
  makerApple?: Record<string, any>  // Apple Maker Note; numeric string keys
}

The well-known dictionaries (exif / gps / tiff / iptc) use Apple's CGImageProperties key names verbatim (gps.Latitude, exif.DateTimeOriginal, ...).

makerApple is the Apple Maker Note, whose keys are numeric strings. The one you're most likely to care about is '17', the Live Photo asset identifier that pairs a still image with its .mov:

const meta = await ImageIO.readMetadata("/path/to/live.heic")
console.log(meta.makerApple?.["17"])   // e.g. "9F1C...-...."

You can write it too, but you rarely should — use LivePhoto.createFromVideo to build a valid Live Photo pair rather than stamping identifiers by hand. Only containers with an EXIF Maker Note (jpeg / heic) can carry it.


ImageIO.writeImage(options)

function writeImage(options: ImageWriteOptions): Promise<void>

Encodes and writes an image to to. Provide exactly one of image or source:

FieldTypeNotes
image?UIImageRe-encode from a decoded bitmap. The original file's metadata is not preserved — only the metadata you pass is written.
source?string | DataCopy from an original encoded image, preserving its metadata, then overlay the metadata you pass.
tostringOutput file path. An existing file is overwritten.
format?'jpeg' | 'png' | 'heic' | 'tiff' | 'gif'Required with image; defaults to the source's format with source.
quality?numberLossy compression 0..1 (jpeg / heic only).
metadata?ImageMetadataMerged on top of the source's metadata when using source.

Tag a photo with GPS while keeping its EXIF

Use the source variant — re-encoding through a UIImage would drop the original EXIF:

await ImageIO.writeImage({
  source: "/path/to/original.jpg",   // keeps original EXIF / TIFF
  to: "/path/to/tagged.jpg",
  metadata: { gps: { Latitude: 10.0, LatitudeRef: "N" } },  // overlay GPS
})

Caveats

  • image drops original metadata. A UIImage is a decoded bitmap. To preserve a file's existing EXIF/GPS, use the source variant, not image.
  • quality only applies to jpeg / heic. It's ignored for png / tiff / gif.
  • HEIC encoding requires a device/simulator that supports the HEVC image encoder; on older simulators HEIC may fail — fall back to jpeg if writeImage rejects.
  • Key names are raw CGImageProperties keys. When writing exif / gps / tiff / iptc, use Apple's key names (e.g. Latitude, LatitudeRef, DateTimeOriginal). makerApple keys are numeric strings ('17', ...).
  • makerApple needs a Maker Note container. It only survives in jpeg / heic; writing it to png / tiff / gif silently does nothing.