Swift Markdown Kit · DOCS
Reference
Reference
Views and controllers
| Type | Use |
|---|---|
MarkdownRenderView |
SwiftUI, one document. |
MarkdownRenderViewController |
UIKit, one document. |
MarkdownChatRenderView |
SwiftUI, a whole conversation. |
MarkdownChatRenderViewController |
UIKit, a whole conversation. |
MarkdownChatRenderProxy |
Imperative control of a SwiftUI chat view. |
MarkdownRenderKit |
version, bridgeVersion, licenseDiagnostics(). |
Document methods
render(_:) · renderStream(_:) · startStreaming() ·
appendChunk(_:isFinal:) · finishStreaming() · clear() · reload() ·
contentHeight · licenseStatus
Conversation methods
setMessages(_:) · appendMessage(_:) · updateMessage(_:) ·
appendChunk(_:to:isFinal:) · appendReasoningChunk(_:to:isFinal:) ·
finishReasoning(for:) · setReasoningExpanded(_:for:) ·
finishMessage(_:) · removeMessage(_:) · clear() ·
scrollToBottom(animated:) · contentHeight · licenseStatus
MarkdownRenderOptions
| Option | Default | Meaning |
|---|---|---|
colorScheme |
.auto |
.auto, .light, .dark. |
theme |
.system |
.system or .github, plus token overrides. |
extensions |
[] |
Custom inline syntax. |
interaction |
.automatic |
Who handles link and image taps. |
isScrollEnabled |
true |
Off when embedding inside your own scroll view. |
backgroundColor |
.clear |
Renderer background. |
contentPadding |
16pt all round | Inset between content and edges. |
bottomGap |
0 |
Extra space under the last block, for an overlaying composer. |
markdown |
see below | Parser capabilities. |
streamingMode |
.incremental |
.fullRerender re-renders everything on each flush. |
longBlockStreaming |
.throttled |
.deferred holds a long block until it completes. |
longBlockThreshold |
512 |
Characters before the strategy applies. |
baseFontSize |
16 |
Before Dynamic Type scaling. |
respectsDynamicType |
true |
Follow the system text size. |
minFontScale / maxFontScale |
0.85 / 1.6 |
Clamp on the Dynamic Type multiplier. |
heightChangeDebounceInterval |
0.08 |
Debounce on height reporting while streaming. |
copyText / copiedText / copyFailedText |
localized | Code block copy button labels. Default to the reader's language — see Localization. |
MarkdownRenderLocalization
The language the SDK draws its own strings in, and the strings themselves. Full detail in Localization.
| Member | Meaning |
|---|---|
language |
.automatic (default, follows the device), .english, .simplifiedChinese, .custom(_:). |
availableLanguages |
Localization codes this build ships, e.g. ["en", "zh-Hans"]. |
codeCopy / codeCopied / codeCopyFailed |
Code block copy button, resolved. |
messageCopy / messageCopied / messageRetry / messageEdit |
Message action accessibility labels, resolved. |
reasoningThinking / reasoningCompleted / reasoningDuration |
Reasoning fold headers, resolved. |
MarkdownRenderOptions.MarkdownConfig
| Option | Default |
|---|---|
allowRawHTML |
false |
linkify |
true |
typographer |
true |
breaks |
false |
taskLists |
true |
emoji |
true |
math |
true |
reasoning |
enabled |
MarkdownChatRenderOptions
| Option | Default | Meaning |
|---|---|---|
renderOptions |
— | The document options above, applied to every message. |
interaction |
.automatic |
Shorthand for renderOptions.interaction. |
reasoning |
enabled | The reasoning fold. |
messageActions |
copy only | Per-message toolbar. |
streamingPresentation |
.smooth |
.immediate shows each chunk as it lands. |
autoScrollBehavior |
.nearBottom |
.always, .never. |
preservesUserScroll |
true |
Stop following once the reader scrolls up. |
bottomThreshold |
96 |
Points from the bottom that still count as "at the bottom". |
messageSpacing |
14 |
Points between messages. |
maxMessageWidth |
.full |
Width of the reading column. |
userMessageMaxWidth |
.fraction(0.82) |
Width of the user's own bubbles. |
chunkCoalescingInterval |
1/30 s |
Gather tokens before crossing into the web view; 0 disables. |
Events
MarkdownRenderEvent for documents, MarkdownChatRenderEvent for
conversations. The chat variant adds viewportChanged and messageAction, and
wraps actions with the message id they came from.
| Event | Fires when |
|---|---|
.ready |
The renderer finished loading and queued commands start running. |
.rendered(height:) |
Exactly twice per content cycle: first paint, and the final flush. |
.heightChanged(_) |
Height changed in between — streaming, image loads, Dynamic Type. Debounced while streaming. |
.viewportChanged(_) |
Scroll position and whether the reader is near the bottom. |
.messageAction(_) |
Copy, retry or edit tapped on a message. |
.action(_) |
Everything below. |
.error(_) |
A structured failure carrying a stable code. |
Actions
Requests — nothing happens unless you act:
| Action | Meaning |
|---|---|
.linkTapped(URL) |
A link was tapped and interaction.links is .handledByHost. |
.imageTapped(URL?) |
An image was tapped and interaction.images is .handledByHost. |
.extensionTapped(name:action:value:) |
A custom inline extension was tapped. |
.custom(name:payload:) |
An unrecognised bridge message. |
Notifications — the SDK already acted:
| Action | Meaning |
|---|---|
.didOpenLink(URL) |
Opened in the in-app browser, or handed to the system for mailto/tel. |
.didPresentImage(URL) |
The built-in viewer was presented. |
.linkBlocked(url:scheme:) |
The scheme is not in allowedLinkSchemes; nothing was opened. |
.codeCopied(text:language:) |
Copied to the pasteboard. |
.codeCopyFailed(text:language:error:) |
Copy failed. |
.reasoningToggled(isExpanded:) |
The reader opened or closed a reasoning fold. |
.taskToggled(isChecked:text:) |
A task list checkbox changed. |
Errors
MarkdownRenderError carries reason, a human-readable message, and a stable
code suitable for logging.
| code | Meaning |
|---|---|
licenseMissing |
No .smklicense in Copy Bundle Resources. |
licenseInvalid |
Wrong envelope format, bad signature, or malformed payload. |
licenseUnknownSigningKey |
Signed by a key this SDK does not trust — usually a test license paired with a production build. |
licenseWrongIssuerEnvironment |
Issued by the sandbox issuer; a production SDK accepts production only. |
licenseUnauthorizedTeamId |
The app's signing team does not match the license. |
licenseTeamIdentifierUnavailable |
The Team ID could not be read — expected on the Simulator. |
licenseUnauthorizedBundleId |
The bundle identifier is not covered by the license. |
expiredTrialLicense |
A trial license past its validUntil. |
sdkReleaseNotCovered |
This SDK build was released after the license's updatesUntil; renew to use it. |
releaseMetadataMissing |
The framework is missing its release metadata — a broken build. |
resourceMissing / resourceInvalid / resourceKeyInvalid / resourceDecryptionFailed |
The bundled render core could not be loaded. |
webViewLoadFailed |
The web view failed to load the renderer. |
webContentProcessTerminated |
WebKit reclaimed the content process; the SDK reloads and replays automatically. |
renderFailed / serializationFailed / copyFailed |
A runtime operation failed. |
Every license* code is a diagnostic, not a failure. Rendering continues;
the build is badged. See Licensing.
Versioning
MarkdownRenderKit.version // SDK version, e.g. "0.0.10"
MarkdownRenderKit.bridgeVersion // native ↔ web message contract version
The framework ships with library evolution enabled. Within a major version, public declarations are only ever added — an app compiled against an earlier build keeps linking against a later one without being rebuilt.