Skip to content

3.2.0

Latest

Choose a tag to compare

@choule99 choule99 released this 08 Oct 12:26
· 2 commits to main since this release
Immutable release. Only release title and notes can be modified.
3.2.0
60a26eb

Performance and resource-usage improvements for both libraries, plus a move to Xcode 27.

MarkdownUI

Behavior changes

  • DefaultImageProvider and DefaultInlineImageProvider now default to .downsampled(maximumPixelDimension: 2048). Large network images decode with at most 2048 pixels on their longest side and keep their original intrinsic size. Pass resolution: .original to keep the previous behavior.
  • The new Resolution.downsampled(maximumPixelDimension:) case may require updating exhaustive switch statements over Resolution.
  • Image responses are capped at 50 MB and 32 megapixels decoded.

Additions

  • AssetInlineImageProvider.init(bundle:) looks up images by the URL's last path component.

Performance

  • Streamed sources reparse only the changed tail instead of the whole document.
  • Builder Markdown strings are cached, and nested image scans are deferred.
  • Parsing switches on integer cmark node types.
  • Lists use fewer layers per item and scope marker widths to their own list.
  • FlowLayout keeps several measurements per layout pass.
  • Inline text fragments with matching attributes are coalesced.
  • Heading slugs are computed in one pass.
  • Network images:
    • Load through a dedicated URLSession with separate network and decode concurrency limits.
    • Revalidate with ETag/Last-Modified.
    • Are held in a decoded-image cache with count-bounded LRU eviction.
  • Loaded block images are kept when their views reappear.
  • The macOS asset image provider caches bundle images.
  • Hashable inline image providers are identified by value.
  • The syntax highlighting cache uses LRU eviction and hashes keys outside its lock.
  • Long or streaming documents are now documented to use .lazy rendering.

MarkdownUIEditor

Images

  • Images decode off the main actor at display resolution, with size and pixel limits.
  • Cached images revalidate with conditional requests.
  • Images load through a dedicated URL session.
  • Default image providers share one decoded-image cache whose cost is measured from the retained bitmap.

Editing

  • After structural edits, only the top-level blocks that changed are replaced.
  • Edited blocks are written back only when an edit actually changes them.
  • Source binding echoes are recognized without reparsing the document.
  • Toolbar command state is evaluated once per update.
  • Projection lookups, inline attribute resolution, and text-run merging no longer scale with document size per edit.
  • Task checkbox placement is skipped when its layout inputs are unchanged.

Tables

  • Unchanged tables keep their attachments and grids when text is rendered again.
  • Changed tables update their grid in place for row, column, and cell changes, including after table commands and undo.
  • Each distinct table cell's text is projected once.
  • A growing UIKit table relayouts only itself.

Tooling

  • Builds and tests use Xcode 27 with the 27.0 SDKs (Swift 6.4).
  • Snapshot baselines are recorded on macOS 27 and iOS 27.
  • CI runs on GitHub-hosted runners with formatting, lint, and per-platform build checks.
  • Documentation builds and publishing are centralized.

Full Changelog: 3.1.0...3.2.0