Files
Charles Wiltgen 30955f9e95 feat: document 27.0 SDK API additions across media, macOS, testing, and TextKit
APIs that shipped in the 27.0 SDK but had no Axiom coverage, each checked
against the RC SDK and the published snippets compiled.

- AVFoundation: async session activation and the deactivation and
  resumption notifications that replace interruption types; throwing
  AVAudioEngine and node APIs (connectNode, playAudio, installAudioTap)
  that replace calls that trapped on misuse; realtime-safe render blocks
  are ObjC-only.
- PhotoKit: Apple Reference Image viewer, the persistent change history
  observer, asset keyword/rating/caption editing, the root folder
  collection, synced-only identifier mapping, and background resource
  upload configuration.
- ScreenCaptureKit: clip buffering, the recording editor, new error codes,
  and a per-platform availability table now that it ships beyond macOS.
  The Presenter Overlay delegate methods use their shipped names
  (outputVideoEffectDidStart/Stop), and the iOS screen-capture sample
  compiles under Swift 6.
- macOS 27 denies another team's app or app group container without a
  prompt; the sandbox skill explains the failure and the fixes.
- Background Assets: the languageChange content request (a build break
  for exhaustive switches), localized file reads, and async exclusive
  control that must be used on both the app and extension side.
- XCUITest drives VoiceOver and asserts spoken output
  (XCUIDevice.shared.voiceOverService).
- TextKit: per-edge block borders, hit-testing transformed text, and
  UITextChecker grammar checking.
- Xcode 27 silently ignores -ld_classic and rejects -ld64; Clang module
  names must be unique per dependency scan.
- Media router rows for 27 camera controls and iPhone Duo camera direction.
2026-09-14 10:35:35 -07:00

6.6 KiB
Raw Permalink Blame History

name, description
name description
textkit-ref Reference — Complete TextKit 2 guide covering architecture, migration from TextKit 1, Writing Tools integration, and SwiftUI TextEditor with AttributedString through iOS 27

TextKit 2 Reference

This reference helps you work with Apple's TextKit 2 framework for custom text rendering, rich text editing, and Writing Tools integration. It covers architecture, migration from TextKit 1, and iOS 2627 features.

When to Use This Reference

Use this reference when you're:

  • Building custom text views or rich text editors
  • Migrating from TextKit 1 to TextKit 2
  • Integrating Writing Tools (iOS 18+)
  • Working with SwiftUI TextEditor and AttributedString (iOS 26+)
  • Debugging text layout issues or unexpected fallbacks to TextKit 1
  • Customizing rendering surfaces or attachment view recycling from inside a UITextView subclass (iOS 27+)
  • Checking grammar programmatically with UITextChecker, styling individual edges of a text block, or hit-testing text drawn through a transform (iOS 27+)

Not sure if you need TextKit 2? If you're using standard Text, TextField, or UILabel, you probably don't. TextKit 2 is for custom text rendering, syntax highlighting, or rich text editing beyond what built-in controls provide.

Example Prompts

Questions you can ask Claude that will draw from this reference:

  • "How do I migrate my text view from TextKit 1 to TextKit 2?"
  • "Why is my UITextView falling back to TextKit 1?"
  • "How do I count lines in TextKit 2 without glyph APIs?"
  • "How do I integrate Writing Tools with my custom text editor?"
  • "How do I use AttributedString with SwiftUI TextEditor in iOS 26?"
  • "What's the difference between NSTextRange and NSRange?"
  • "How do I customize text fragment rendering inside a UITextView without losing input or accessibility?"
  • "How do I recycle inline attachment views in my text editor?"
  • "How do I run grammar checking on a string with UITextChecker?"
  • "How do I put a border on only the bottom edge of an NSTextBlock on iOS?"
  • "My custom text view draws rotated text — how do I make taps select the right characters?"

What's Covered

Core Architecture

  • Three-layer MVC pattern (Model, Controller, View)
  • NSTextContentManager, NSTextLayoutManager, NSTextViewportLayoutController
  • Object-based ranges (NSTextLocation, NSTextRange) vs integer indices

Migration from TextKit 1

  • Paradigm shift from glyphs to elements
  • NSRange ↔ NSTextRange conversion patterns
  • Fallback triggers to avoid (accessing .layoutManager causes one-way fallback)
  • Why glyph APIs are dangerous for international text

Writing Tools (iOS 18+)

  • TextKit 2 requirement for full experience
  • Lifecycle delegate methods
  • Protected ranges for code blocks and quotes
  • Writing Tools Coordinator for custom text engines (iOS 26+)

SwiftUI TextEditor (iOS 26+)

  • AttributedString binding
  • Custom formatting definitions
  • Value constraints
  • Selection handling
  • AttributedString text alignment and line height control
  • Programmatic selection replacement
  • DiscontiguousAttributedSubstring for non-contiguous selections

Viewport Rendering Surfaces & Attachment Reuse (iOS 27)

  • NSTextViewportRenderingSurface render text fragments from a custom view without building a full custom text engine
  • Subclassable viewport delegate on framework text views — override NSTextViewportLayoutControllerDelegate hooks directly inside a UITextView subclass
  • registerTextAttachmentViewProviderReusePolicy(_:forTextAttachmentViewProviderType:) recycle inline attachment views instead of rebuilding them
  • Collapsible content via shouldEnumerate — exclude collapsed paragraphs from layout using the NSTextContentStorageDelegate

Text Blocks, Hit Testing & Grammar Checking (iOS 27)

  • Per-edge NSTextBlock borders, padding, and margins setBorderColor(_:rectEdge:), borderColor(for:), setWidth(_:type:for:rectEdge:), width(for:rectEdge:), widthValueType(for:rectEdge:)
  • Transformed-text hit testing NSTextSelectionDataSource.convertInteractionPoint(_:toContainerAt:)
  • Grammar checking UITextChecker.requestGrammarChecking(of:range:waitForAllResults:), ignoreGrammarRange(_:inSentence:), and the macOS-only grammarDetails keys

Documentation Scope

This page documents the textkit-ref skill in the axiom-uikit suite — a comprehensive reference Claude uses when answering TextKit 2 questions. The skill contains detailed API documentation, code examples, and migration patterns.

For automated scanning: Use the textkit-auditor agent to scan your codebase for TextKit 1 fallback triggers and migration opportunities.

For typography and Dynamic Type: See typography-ref for font handling, text styles, and accessibility considerations.

Key Patterns

Checking for TextKit 2 (Critical)

Always check TextKit 2 first to avoid triggering fallback:

// ✅ GOOD: Check TextKit 2 first
if let textLayoutManager = textView.textLayoutManager {
    // TextKit 2 code
} else if let layoutManager = textView.layoutManager {
    // TextKit 1 fallback only for old OS
}

// ❌ BAD: Accessing .layoutManager triggers one-way fallback
if let layoutManager = textView.layoutManager {
    // You're now stuck in TextKit 1!
}

Creating a TextKit 2 Text View

// iOS 16+ / macOS 13+
let textView = UITextView(usingTextLayoutManager: true)

Writing Tools Integration

// Lifecycle awareness
func textViewWritingToolsWillBegin(_ textView: UITextView) {
    isSyncing = false  // Pause syncing during Writing Tools
}

func textViewWritingToolsDidEnd(_ textView: UITextView) {
    isSyncing = true  // Resume syncing
}

Known Limitations

  • One-way fallback Accessing .layoutManager permanently switches to TextKit 1
  • No glyph APIs Use NSTextLocation and layout fragments instead
  • NSTextTable unsupported Use NSTextList or custom layouts