Swift FormatStyle
Use Foundation's type-safe FormatStyle APIs for user-facing display and ParseableFormatStyle when the same convention must accept input. Route String Catalogs, plurals, localized copy, bundles, and RTL layout to ios-localization; formatting still requires locale review even when no text is translated.
Contents
- Workflow
- Quick Reference
- Selection and Availability
- Parsing
- SwiftUI Integration
- Custom FormatStyle
- Common Mistakes
- Review Checklist
- References
Workflow
- Identify the value's semantic type and whether output is display-only or must round-trip through parsing.
- Select the narrowest built-in style and keep the user's current locale unless a wire format explicitly requires another locale.
- Render the exact UI with representative locales such as
en_US,de_DE,ar_SA, andja_JP. - Check separators, numbering systems, calendars, currency and unit conventions, text direction, and layout.
- If output or parsing fails, fix the style or surrounding copy, restore the input fixture, and rerun the same locale matrix.
Load FormatStyle Recipes [blocked] when implementation needs concrete modifiers, date intervals, relative dates, duration patterns, measurements, names, lists, byte counts, or URL component controls.
Quick Reference
Selection and Availability
- Prefer
FormatStyleover legacyNumberFormatter,DateFormatter,DateComponentsFormatter, and manual interpolation for new iOS 15+ code. Durationformat styles andURL.FormatStylerequire iOS 16+.Date.AnchoredRelativeFormatStylerequires iOS 18+ and formats relative to a fixed anchor rather than the current moment.- Omit
.locale(...)for normal UI so the style inherits the user's locale. Use a fixed locale only for an explicit protocol or test fixture. - Treat relative date output as standalone text unless the entire sentence is localized around it.
Docs: FormatStyle
Parsing
Use the matching parseable style when users edit or import formatted values:
The fixed locale above is appropriate only because the input contract is explicitly en_US. For normal UI input, use the user's locale and test round trips with representative decimal separators, currency placement, calendars, and numbering systems.
SwiftUI Integration
Prefer Text(_:format:) so SwiftUI owns the formatted value:
For every user-facing formatted Text, preview or test the exact screen across the locale matrix. Use Text(.now, style: .timer), Text(.now, style: .relative), or Text(timerInterval:) for live-updating time displays rather than manually scheduling string refreshes.
Custom FormatStyle
Create a custom style only when built-in composition cannot express the domain convention. FormatStyle refines Codable and Hashable; keep styles as reusable values and add ParseableFormatStyle only when input must round-trip.
Custom styles still need locale and accessibility review; a compact English suffix may not be suitable for every locale.
Common Mistakes
Review Checklist
- Semantic value type and display-versus-parse requirement identified
- Built-in
FormatStyleused where it can express the convention - Availability gated beside iOS 16+ and iOS 18+ APIs
- Currency uses an ISO 4217 code; exact decimal values use
Decimal - User locale inherited unless a protocol explicitly fixes it
- Relative date text stands alone or the full sentence is localized
- URL components and measurement
usage:are deliberate - SwiftUI uses
Text(_:format:)for formatted values - Exact rendered UI and parse round trips pass the representative-locale matrix
References
- Detailed recipes and modifiers: references/formatstyle-recipes.md [blocked]
- Apple docs: FormatStyle · ParseableFormatStyle · Date.FormatStyle · Duration.TimeFormatStyle · URL.FormatStyle


