mcpField
S
swift-formatstyle

swift-formatstyle

github.com/dpearson2699开发1.2k2.7k 次安装13 周前更新
代码仓库

关于 swift-formatstyle

swift-formatstyle 是一项开发技能,指导使用 Swift 的类型安全格式化与解析 API。内容涵盖本地化显示、SwiftUI 集成,以及跨代表性地区设置测试呈现结果。

主要功能

  1. 01选择内置 FormatStyle API
  2. 02用匹配样式解析格式化输入
  3. 03在 SwiftUI 中用 Text(_:format:) 格式化
  4. 04跨代表性地区设置检查输出
  5. 05内置样式不足时创建自定义样式

适用场景

  1. 01本地化日期、数字、货币和度量值
  2. 02接收需要往返解析的用户输入
  3. 03检查不同地区设置下的格式化界面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dpearson2699/swift-ios-skills --skill swift-formatstyle

安装后在 Claude Code 中输入/swift-formatstyle确认已加载。

附带文件evals/evals.jsonreferences/formatstyle-recipes.md

详细介绍

Swift FormatStyle

使用 Foundation 类型安全的 FormatStyle API 来面向用户显示内容;当同一格式约定也必须接受输入时,使用 ParseableFormatStyle。String Catalog、复数形式、本地化文案、Bundle 和 RTL 布局请交由 ios-localization 处理;即使没有翻译任何文本,格式设置仍需经过区域设置审核。

目录

工作流

  1. 确定值的语义类型,以及输出是仅用于显示还是必须支持往返解析。
  2. 选择范围最窄的内置样式;除非线格式明确要求使用其他区域设置,否则保留用户当前的区域设置。
  3. 使用具有代表性的区域设置(如 en_US、de_DE、ar_SA 和 ja_JP)渲染实际 UI。
  4. 检查分隔符、数字系统、日历、货币和单位约定、文本方向及布局。
  5. 如果输出或解析失败,修正样式或周边文案,恢复输入测试数据,然后重新运行相同的区域设置矩阵。

实现需要具体修饰符、日期区间、相对日期、时长模式、度量、姓名、列表、字节数或 URL 组件控制时,请加载 FormatStyle Recipes。

快速参考

值默认样式重要限制
Int、Double.number仅在需要时配置精度、舍入、分组、记数法或正负号。
Decimal.number、.percent、.currency(code:)精确的十进制显示和解析优先使用此类型。
货币.currency(code:)传入 ISO 4217 代码;切勿硬编码货币符号。
百分比.percent确认输入是分数(0.85)还是整数百分比(85)。
Date.dateTime、.relative、.interval相对日期通常应独立显示,而非嵌入句子中。
Duration.time(pattern:)、.units(allowed:width:)需要 iOS 16+;根据需要选择紧凑时钟格式或带标签的单位。
Measurement.measurement(width:usage:)usage: 控制符合区域设置的换算策略。
PersonNameComponents.name(style:)不要手动拼接姓名各部分。
集合.list(type:width:)让区域设置规则决定分隔符和连接词。
字节数.byteCount(style:)明确选择文件、内存、十进制或二进制语义。
URL.url需要 iOS 16+;查询、端口和片段是可选的显示组件。

选择与可用性

  • 对于新的 iOS 15+ 代码,优先使用 FormatStyle,而不是旧版 NumberFormatter、DateFormatter、DateComponentsFormatter 和手动插值。
  • Duration 格式样式和 URL.FormatStyle 需要 iOS 16+。
  • Date.AnchoredRelativeFormatStyle 需要 iOS 18+,其格式以固定锚点为基准,而非当前时刻。
  • 常规 UI 中省略 .locale(...),让样式继承用户的区域设置。仅在协议明确要求或测试数据需要时使用固定区域设置。
  • 除非整个句子都已围绕相对日期进行本地化,否则应将相对日期作为独立文本处理。

文档:FormatStyle

解析

用户需要编辑或导入已格式化的值时,使用匹配的可解析样式:

let style = Decimal.FormatStyle.Currency(code: "USD")
    .locale(Locale(identifier: "en_US"))

let value = try Decimal("$3,500.63", format: style)
let display = value.formatted(style)

上面的固定区域设置仅适用于输入约定明确规定为 en_US 的情况。对于常规 UI 输入,应使用用户的区域设置,并使用具有代表性的十进制分隔符、货币位置、日历和数字系统测试往返转换。

SwiftUI 集成

优先使用 Text(_:format:),让 SwiftUI 管理格式化后的值:

Text(price, format: .currency(code: currencyCode))
Text(date, format: .dateTime.month().day().year())
Text(duration, format: .units(allowed: [.minutes, .seconds]))

对于每个面向用户的格式化 Text,都应在区域设置矩阵中预览或测试实际屏幕。对于实时更新的时间显示,请使用 Text(.now, style: .timer)、Text(.now, style: .relative) 或 Text(timerInterval:),而不是手动安排字符串刷新。

自定义 FormatStyle

仅当内置组合无法表达领域惯例时,才创建自定义样式。FormatStyle 继承了 Codable 和 Hashable;应将样式作为可复用的值,仅在输入必须支持往返解析时才添加 ParseableFormatStyle。

struct AbbreviatedCountStyle: FormatStyle {
    func format(_ value: Int) -> String {
        switch value {
        case ..<1_000: "\(value)"
        case 1_000..<1_000_000: String(format: "%.1fK", Double(value) / 1_000)
        default: String(format: "%.1fM", Double(value) / 1_000_000)
        }
    }
}

extension FormatStyle where Self == AbbreviatedCountStyle {
    static var abbreviatedCount: Self { .init() }
}

自定义样式仍需进行区域设置和无障碍审核;简短的英文后缀未必适用于所有区域设置。

常见错误

错误修正方法
在视图代码中手动格式化或分配旧式格式化器使用匹配的 FormatStyle 和 Text(_:format:)。
硬编码货币符号或区域设置传入 ISO 货币代码,并沿用用户的区域设置,除非约定另有要求。
对精确十进制输入使用二进制浮点数使用 Decimal.FormatStyle 及其对应的解析策略。
认为 URL.formatted() 会保留所有组件仅当这些组件应显示时,才显式启用 .port(.always)、.query(.always) 或 .fragment(.always)。
将相对日期输出嵌入较长的句子单独显示,或对完整句子进行本地化。
在行文中使用时钟样式的时长对带标签的输出使用 .units(allowed:width:)。
未明确指定测量值转换方式选择适合 UI 的 usage:。
只抽查一种区域设置使用相同的实际屏幕测试样例检查多个有代表性的区域设置,并修复后重新运行失败项。

审核清单

  • 已确定语义值类型,以及需要显示还是解析
  • 在能够表达相关惯例时使用内置 FormatStyle
  • 在 iOS 16+ 和 iOS 18+ API 旁设置可用性限制
  • 货币使用 ISO 4217 代码;精确十进制值使用 Decimal
  • 除非协议明确规定,否则沿用用户的区域设置
  • 相对日期文本单独显示,或对完整句子进行本地化
  • 明确设置 URL 组件和测量值的 usage:
  • SwiftUI 对格式化值使用 Text(_:format:)
  • 实际渲染的 UI 和解析往返均通过有代表性的区域设置矩阵测试

参考资料

评论

支持 Markdown