关于 axiom-localization
面向 Apple 平台开发者的本地化与国际化指南,重点介绍 Xcode String Catalog、SwiftUI/UIKit API、复数形式、RTL 支持及旧格式迁移。
主要功能
- 01管理 Xcode String Catalog
- 02本地化 SwiftUI 和 UIKit
- 03处理复数与 RTL 布局
- 04按区域设置格式化数据
- 05迁移旧本地化文件
适用场景
- 01为应用添加多语言支持
- 02排查缺失翻译或复数错误
- 03支持阿拉伯语和希伯来语布局
- 04将 .strings 文件迁移至 .xcstrings
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-localization安装后在 Claude Code 中输入/axiom-localization确认已加载。
详细介绍
本地化与国际化
使用 String Catalogs 进行应用本地化的综合指南。荣获 Apple Design Award 包容性奖项的应用始终支持多种语言,并提供出色的 RTL(从右向左)支持。
概述
String Catalogs(.xcstrings)是 Xcode 15 用于管理应用本地化的统一格式。它们以单一的 JSON 格式取代旧版 .strings 和 .stringsdict 文件,更易于维护、比较差异并集成到翻译工作流中。
本技能涵盖 String Catalogs、SwiftUI/UIKit 本地化 API、复数处理、RTL 支持、区域设置感知格式化,以及从旧版格式迁移的策略。
何时使用本技能
- 在 Xcode 15+ 中设置 String Catalogs
- 本地化 SwiftUI 和 UIKit 应用
- 正确处理复数形式(对许多语言至关重要)
- 支持 RTL 语言(阿拉伯语、希伯来语)
- 根据区域设置格式化日期、数字和货币
- 从旧版
.strings/.stringsdict文件迁移 - 为 App Shortcuts 和 App Intents 准备本地化内容
- 排查缺失的翻译或不正确的复数形式
系统要求
- Xcode 15+:支持 String Catalogs(
.xcstrings) - Xcode 26+:支持自动符号生成、
#bundle宏和 AI 驱动的注释生成 - iOS 15+:支持
LocalizedStringResource - iOS 16+:支持 App Shortcuts 本地化
- 更早版本的 iOS 使用旧版
.strings文件
第 1 部分:String Catalogs(WWDC 2023/10155)
创建 String Catalog
方法 1:Xcode 导航器
- File → New → File
- 选择 "String Catalog"
- 为其命名(例如,
Localizable.xcstrings) - 添加到目标
方法 2:自动提取
Xcode 15 可以自动提取以下内容中的字符串:
- SwiftUI 视图(
Text、Label、Button中的字符串字面量) - Swift 代码(
String(localized:)) - Objective-C(
NSLocalizedString) - C(
CFCopyLocalizedString) - Interface Builder 文件(
.storyboard、.xib) - Info.plist 值
- App Shortcuts 短语
所需构建设置:
- "Use Compiler to Extract Swift Strings" → Yes
- "Localization Prefers String Catalogs" → Yes
String Catalog 结构
每个条目包含:
- 键:唯一标识符(默认值:英文字符串)
- 默认值:缺少翻译时的回退值
- 注释:为译者提供的上下文
- 字符串表:组织容器(默认值:"Localizable")
.xcstrings JSON 示例:
{
"sourceLanguage" : "en",
"strings" : {
"Thanks for shopping with us!" : {
"comment" : "Label above checkout button",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Thanks for shopping with us!"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "¡Gracias por comprar con nosotros!"
}
}
}
}
},
"version" : "1.0"
}
翻译状态
Xcode 会跟踪每项翻译的状态:
- 新增(⚪)- 字符串尚未翻译
- 需要审核(🟡)- 源内容已更改,翻译可能已过时
- 已审核(✅)- 翻译已批准且为最新版本
- 过时(🔴)- 源代码中已找不到该字符串
工作流:
- 开发者添加字符串 → 新增
- 译者添加翻译 → 已审核
- 开发者更改源内容 → 需要审核
- 译者更新翻译 → 已审核
- 开发者移除代码 → 过时
第 2 部分:SwiftUI 本地化
LocalizedStringKey(自动)
带有 String 参数的 SwiftUI 视图会自动支持本地化:
// ✅ Automatically localizable
Text("Welcome to WWDC!")
Label("Thanks for shopping with us!", systemImage: "bag")
Button("Checkout") { }
// Xcode extracts these strings to String Catalog
工作原理:SwiftUI 在内部使用 LocalizedStringKey,从 String Catalogs 中查找字符串。
使用注释的 String(localized:)
在 Swift 代码中显式进行本地化:
// Basic
let title = String(localized: "Welcome to WWDC!")
// With comment for translators
let title = String(localized: "Welcome to WWDC!",
comment: "Notification banner title")
// With custom table
let title = String(localized: "Welcome to WWDC!",
table: "WWDCNotifications",
comment: "Notification banner title")
// With default value (key ≠ English text)
let title = String(localized: "WWDC_NOTIFICATION_TITLE",
defaultValue: "Welcome to WWDC!",
comment: "Notification banner title")
最佳实践:始终添加 comment,为译者提供上下文。
LocalizedStringResource(延迟本地化)
用于将可本地化字符串传递给其他函数:
import Foundation
struct CardView: View {
let title: LocalizedStringResource
let subtitle: LocalizedStringResource
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 10.0)
VStack {
Text(title) // Resolved at render time
Text(subtitle)
}
.padding()
}
}
}
// Usage
CardView(
title: "Recent Purchases",
subtitle: "Items you've ordered in the past week."
)
主要区别:LocalizedStringResource 会延迟到使用时才查找字符串,因此自定义视图可以完全支持本地化。
使用 Markdown 的 AttributedString
// Markdown formatting is preserved across localizations
let subtitle = AttributedString(localized: "**Bold** and _italic_ text")
第 3 部分:UIKit 与 Foundation
NSLocalizedString 宏
// Basic
let title = NSLocalizedString("Recent Purchases", comment: "Button Title")
// With table
let title = NSLocalizedString("Recent Purchases",
tableName: "Shopping",
comment: "Button Title")
// With bundle
let title = NSLocalizedString("Recent Purchases",
tableName: nil,
bundle: .main,
value: "",
comment: "Button Title")
Bundle.localizedString
let customBundle = Bundle(for: MyFramework.self)
let text = customBundle.localizedString(forKey: "Welcome",
value: nil,
table: "MyFramework")
自定义宏
// Objective-C
#define MyLocalizedString(key, comment) \
[myBundle localizedStringForKey:key value:nil table:nil]
Info.plist 本地化
本地化应用名称、权限等内容:
- 选择
Info.plist - Editor → Add Localization
- 为每种语言创建
InfoPlist.strings:
// InfoPlist.strings (Spanish)
"CFBundleName" = "Mi Aplicación";
"NSCameraUsageDescription" = "La app necesita acceso a la cámara para tomar fotos.";
第 4 部分:复数形式
不同语言的复数规则各不相同:
- 英语:2 种形式(one、other)
- 俄语:3 种形式(one、few、many)
- 波兰语:3 种形式(one、few、other)
- 阿拉伯语:6 种形式(zero、one、two、few、many、other)
SwiftUI 复数处理
// Xcode automatically creates plural variations
Text("\(count) items")
// With custom formatting
Text("\(visitorCount) Recent Visitors")
在 String Catalog 中:
{
"strings" : {
"%lld Recent Visitors" : {
"localizations" : {
"en" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld Recent Visitor"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld Recent Visitors"
}
}
}
}
}
}
}
}
}
XLIFF 导出格式
导出以供翻译时(文件 → 导出本地化):
旧版(stringsdict):
<trans-unit id="/%lld Recent Visitors:dict/NSStringLocalizedFormatKey:dict/:string">
<source>%#@recentVisitors@</source>
</trans-unit>
<trans-unit id="/%lld Recent Visitors:dict/recentVisitors:dict/one:dict/:string">
<source>%lld Recent Visitor</source>
<target>%lld Visitante Recente</target>
</trans-unit>
String Catalog(更简洁):
<trans-unit id="%lld Recent Visitors|==|plural.one">
<source>%lld Recent Visitor</source>
<target>%lld Visitante Recente</target>
</trans-unit>
<trans-unit id="%lld Recent Visitors|==|plural.other">
<source>%lld Recent Visitors</source>
<target>%lld Visitantes Recentes</target>
</trans-unit>
使用复数变量进行替换
// Multiple variables with different plural forms
let message = String(localized: "\(songCount) songs on \(albumCount) albums")
Xcode 会为每个变量的复数形式创建变体:
songCount:one、otheralbumCount:one、other- 组合总数:2 × 2 = 4 个翻译条目
第 5 部分:设备和宽度变体
特定设备的字符串
不同平台使用不同文本:
// Same code, different strings per device
Text("Bird Food Shop")
String Catalog 变体:
{
"Bird Food Shop" : {
"localizations" : {
"en" : {
"variations" : {
"device" : {
"applewatch" : {
"stringUnit" : {
"value" : "Bird Food"
}
},
"other" : {
"stringUnit" : {
"value" : "Bird Food Shop"
}
}
}
}
}
}
}
}
结果:
- iPhone/iPad:“鸟食商店”
- Apple Watch:“鸟食”(适用于小屏幕的较短文本)
宽度变体
用于动态字体和尺寸类别:
Text("Application Settings")
String Catalog 可以为较窄的宽度提供较短的文本。
第 6 部分:RTL 支持
布局镜像
SwiftUI 会自动为 RTL 语言镜像布局:
// ✅ Automatically mirrors for Arabic/Hebrew
HStack {
Image(systemName: "chevron.right")
Text("Next")
}
// iPhone (English): [>] Next
// iPhone (Arabic): Next [<]
Leading/Trailing 与 Left/Right
始终使用语义方向:
// ✅ Correct - mirrors automatically
.padding(.leading, 16)
.frame(maxWidth: .infinity, alignment: .leading)
// ❌ Wrong - doesn't mirror
.padding(.left, 16)
.frame(maxWidth: .infinity, alignment: .left)
图像和图标
标记应翻转或不应翻转的图像:
// ✅ Directional - mirrors for RTL
Image(systemName: "chevron.forward")
// ✅ Non-directional - never mirrors
Image(systemName: "star.fill")
// Custom images
Image("backButton")
.flipsForRightToLeftLayoutDirection(true)
在 RTL 模式下测试
Xcode 方案:
- 编辑方案 → 运行 → 选项
- 应用语言:阿拉伯语 / 希伯来语
- 或:应用语言 → 从右到左伪语言
模拟器: 设置 → 通用 → 语言与地区 → 首选语言顺序
SwiftUI 预览:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environment(\.layoutDirection, .rightToLeft)
.environment(\.locale, Locale(identifier: "ar"))
}
}
第 7 部分:区域设置感知格式化
DateFormatter
let formatter = DateFormatter()
formatter.locale = Locale.current // ✅ Use current locale
formatter.dateStyle = .long
formatter.timeStyle = .short
let dateString = formatter.string(from: Date())
// US: "January 15, 2024 at 3:30 PM"
// France: "15 janvier 2024 à 15:30"
// Japan: "2024年1月15日 15:30"
切勿硬编码日期格式字符串:
// ❌ Wrong - breaks in other locales
formatter.dateFormat = "MM/dd/yyyy"
// ✅ Correct - adapts to locale
formatter.dateStyle = .short
用于货币的 NumberFormatter
let formatter = NumberFormatter()
formatter.locale = Locale.current
formatter.numberStyle = .currency
let priceString = formatter.string(from: 29.99)
// US: "$29.99"
// UK: "£29.99"
// Japan: "¥30" (rounds to integer)
// France: "29,99 €" (comma decimal, space before symbol)
MeasurementFormatter
let distance = Measurement(value: 100, unit: UnitLength.meters)
let formatter = MeasurementFormatter()
formatter.locale = Locale.current
let distanceString = formatter.string(from: distance)
// US: "328 ft" (converts to imperial)
// Metric countries: "100 m"
特定区域设置的排序
let names = ["Ångström", "Zebra", "Apple"]
// ✅ Locale-aware sort
let sorted = names.sorted { (lhs, rhs) in
lhs.localizedStandardCompare(rhs) == .orderedAscending
}
// Sweden: ["Ångström", "Apple", "Zebra"] (Å comes first in Swedish)
// US: ["Ångström", "Apple", "Zebra"] (Å treated as A)
第 8 部分:App Shortcuts 本地化
带参数的短语
import AppIntents
struct ShowTopDonutsIntent: AppIntent {
static var title: LocalizedStringResource = "Show Top Donuts"
@Parameter(title: "Timeframe")
var timeframe: Timeframe
static var parameterSummary: some ParameterSummary {
Summary("\(.applicationName) Trends for \(\.$timeframe)") {
\.$timeframe
}
}
}
String Catalog 会自动提取:
- 意图标题
- 参数名称
- 带占位符的短语模板
本地化短语:
English: "Food Truck Trends for this week"
Spanish: "Tendencias de Food Truck para esta semana"
AppShortcutsProvider 本地化
struct FoodTruckShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: ShowTopDonutsIntent(),
phrases: [
"\(.applicationName) Trends for \(\.$timeframe)",
"Show trending donuts for \(\.$timeframe) in \(.applicationName)",
"Give me trends for \(\.$timeframe) in \(.applicationName)"
]
)
}
}
Xcode 会将全部 3 个短语提取到 String Catalog 中以供翻译。
第 9 部分:从旧版迁移
将 .strings 转换为 .xcstrings
自动迁移:
- 在导航器中选择
.strings文件 - 编辑器 → 转换为 String Catalog
- Xcode 会创建
.xcstrings并保留翻译
手动方式:
- 创建新的 String Catalog
- 构建项目(Xcode 会从代码中提取字符串)
- 通过文件 → 导入本地化(XLIFF)导入翻译
- 删除旧的
.strings文件
转换 .stringsdict
复数文件会自动合并:
- 将
.strings和.stringsdict放在一起 - 转换 → 两者会合并为单个
.xcstrings - 保留复数变体
渐进式迁移策略
阶段 1:新代码使用 String Catalog
- 创建
Localizable.xcstrings - 使用
String(localized:)编写新代码 - 为旧代码保留旧版
.strings文件
阶段 2:迁移现有字符串
- 每次转换一个
.strings表 - 每次转换后测试翻译
- 更新使用旧版
NSLocalizedString调用的代码
阶段 3:移除旧版文件
- 删除
.strings和.stringsdict文件 - 确认所有字符串都在 String Catalog 中
- 提交到 App Store
共存:.strings 和 .xcstrings 可以协同工作,Xcode 会同时检查两者。
常见错误
硬编码字符串
// ❌ Wrong - not localizable
Text("Welcome")
let title = "Settings"
// ✅ Correct - localizable
Text("Welcome") // SwiftUI auto-localizes
let title = String(localized: "Settings")
拼接本地化字符串
// ❌ Wrong - word order varies by language
let message = String(localized: "You have") + " \(count) " + String(localized: "items")
// ✅ Correct - single localizable string with substitution
let message = String(localized: "You have \(count) items")
错误原因:有些语言将数字放在名词前面,有些则放在后面。
缺少复数形式
// ❌ Wrong - grammatically incorrect for many languages
Text("\(count) item(s)")
// ✅ Correct - proper plural handling
Text("\(count) items") // Xcode creates plural variations
忽略 RTL
// ❌ Wrong - breaks in RTL languages
.padding(.left, 20)
HStack {
backButton
Spacer()
title
}
// ✅ Correct - mirrors automatically
.padding(.leading, 20)
HStack {
backButton // Appears on right in RTL
Spacer()
title
}
日期/数字格式错误
// ❌ Wrong - US-only format
let formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yyyy"
// ✅ Correct - adapts to locale
formatter.dateStyle = .short
formatter.locale = Locale.current
忘记添加注释
// ❌ Wrong - translator has no context
String(localized: "Confirm")
// ✅ Correct - clear context
String(localized: "Confirm", comment: "Button to confirm delete action")
影响:“Confirm” 可能表示“验证”或“确认收到”,准确翻译需要结合上下文。
故障排除
字符串未出现在 String Catalog 中
原因:未启用构建设置
解决方案:
- Build Settings → "Use Compiler to Extract Swift Strings" → Yes
- 清理构建文件夹(Cmd+Shift+K)
- 构建项目
应用中未显示翻译
原因 1:项目中未添加语言
- Project → Info → Localizations → + 按钮
- 添加目标语言
原因 2:字符串被标记为 "Stale"
- 移除过时字符串,或确认代码仍在使用这些字符串
复数形式不正确
原因:使用 String.localizedStringWithFormat 而不是 String Catalog
解决方案:使用 String Catalog 的自动复数处理:
// ✅ Correct
Text("\(count) items")
// ❌ Wrong
Text(String.localizedStringWithFormat(NSLocalizedString("%d items", comment: ""), count))
导出的 XLIFF 缺少字符串
原因:未设置 "Localization Prefers String Catalogs"
解决方案:
- Build Settings → "Localization Prefers String Catalogs" → Yes
- 再次导出本地化文件
未显示生成的符号(Xcode 26+)
原因 1:未启用构建设置
解决方案:
- Build Settings → "Generate String Catalog Symbols" → Yes
- 清理构建文件夹(Cmd+Shift+K)
- 重新构建项目
原因 2:未将字符串手动添加到目录中
解决方案:符号仅会为手动添加的字符串生成(String Catalog 中的 + 按钮)。自动提取的字符串不会生成符号。
#bundle 宏无法使用(Xcode 26+)
原因:语法错误或缺少导入
解决方案:
import Foundation // Required for #bundle
Text("My Collections", bundle: #bundle, comment: "Section title")
确认使用的是 #bundle,而不是 .module。
重构为符号失败(Xcode 26+)
原因 1:字符串不在 String Catalog 中
- 确保字符串存在于
.xcstrings文件中 - 构建项目以刷新目录
- 再次尝试重构
原因 2:未启用构建设置
- 在 Build Settings 中启用 "Generate String Catalog Symbols"
- 清理并重新构建
第 10 部分:Xcode 26 本地化增强功能
Xcode 26 引入了通过生成符号实现的类型安全本地化、使用设备端 AI 自动生成注释,以及通过 #bundle 宏改进 Swift Package 支持。这些内容基于 WWDC 2025 第 225 场会议「Explore localization with Xcode」。
生成的符号(类型安全本地化)
问题:基于字符串的本地化在出现拼写错误时会静默失败。
// ❌ Typo - fails silently at runtime
Text("App.HomeScren.Title") // Missing 'e' in Screen
解决方案:Xcode 26 会根据手动添加的字符串生成类型安全符号。
工作原理
- 使用 + 按钮将字符串手动添加到 String Catalog
- 启用构建设置:"Generate String Catalog Symbols"(新项目中默认开启)
- 使用符号而不是字符串
// ✅ Type-safe - compiler catches typos
Text(.appHomeScreenTitle)
符号生成规则
| 字符串类型 | 生成的符号类型 | 用法示例 |
|---|---|---|
| 无占位符 | 静态属性 | Text(.introductionTitle) |
| 有占位符 | 带标签参数的函数 | .subtitle(friendsPosts: 42) |
关键命名转换:
App.HomeScreen.Title→.appHomeScreenTitle- 移除句点,转换为驼峰命名
- 可用于
LocalizedStringResource
代码示例
// SwiftUI views
struct ContentView: View {
var body: some View {
NavigationStack {
Text(.introductionTitle)
.navigationSubtitle(.subtitle(friendsPosts: 42))
}
}
}
// Foundation String
let message = String(localized: .curatedCollection)
// Custom views with LocalizedStringResource
struct CollectionDetailEditingView: View {
let title: LocalizedStringResource
init(title: LocalizedStringResource) {
self.title = title
}
var body: some View {
Text(title)
}
}
CollectionDetailEditingView(title: .editingTitle)
自动生成注释
Xcode 26 使用设备端模型,为可本地化字符串自动生成上下文注释。
启用此功能
- 打开 Xcode Settings → Editing
- 启用 "automatically generate string catalog comments"
- 添加到代码中的新字符串会自动获得生成的注释
示例
对于按钮字符串,Xcode 会生成:
"用于取消删除集合的按钮文本标签"
这些上下文信息有助于译者了解字符串的使用位置和方式。
XLIFF 导出
导出的 XLIFF 文件会标记自动生成的注释:
<trans-unit id="Grand Canyon" xml:space="preserve">
<source>Grand Canyon</source>
<target state="new">Grand Canyon</target>
<note from="auto-generated">Suggestion for searching landmarks</note>
</trans-unit>
优点:
- 节省开发者编写译者上下文说明的时间
- 提供一致、清晰的描述
- 提高翻译质量
Swift Package 和框架的本地化
问题
SwiftUI 默认使用 .main 包。Swift Package 和框架需要引用自己的包:
// ❌ Wrong - uses main bundle, strings not found
Text("My Collections", comment: "Section title")
解决方案:#bundle 宏(Xcode 26 新增)
#bundle 宏会自动引用当前目标对应的正确 bundle:
// ✅ Correct - automatically uses package/framework bundle
Text("My Collections", bundle: #bundle, comment: "Section title")
主要优势:
- 适用于主应用、框架和 Swift Packages
- 向后兼容旧版操作系统
- 无需手动管理
.modulebundle
使用自定义表名
// Main app
Text("My Collections",
tableName: "Discover",
comment: "Section title")
// Framework or Swift Package
Text("My Collections",
tableName: "Discover",
bundle: #bundle,
comment: "Section title")
自定义表的符号访问
使用多个 String Catalog 进行组织时:
默认的“Localizable”表
符号可直接通过 LocalizedStringResource 访问:
Text(.welcomeMessage) // From Localizable.xcstrings
注意:Xcode 会自动解析默认“Localizable”表中的符号。通常无需显式选择表,只有在调试或测试特定目录时才需要这样做。
自定义表
符号嵌套在表的命名空间中:
// From Discover.xcstrings
Text(Discover.featuredCollection)
// From Settings.xcstrings
Text(Settings.privacyPolicy)
大型应用的组织策略:
- Localizable.xcstrings - 应用核心字符串
- FeatureName.xcstrings - 特定功能的字符串(例如,Onboarding、Settings、Discover)
- 优势:更易管理、归属更清晰、XLIFF 组织更完善
两种本地化工作流
Xcode 26 支持两种互为补充的工作流:
工作流 1:字符串提取(推荐用于新项目)
流程:
- 直接在代码中编写字符串
- 使用 SwiftUI 视图(
Text、Button)和String(localized:) - Xcode 会自动提取到 String Catalog
- 利用自动生成的注释
优点:初始设置简单,可立即开始
缺点:对字符串组织的控制较少
// ✅ String extraction workflow
Text("Welcome to WWDC!", comment: "Main welcome message")
工作流 2:生成符号(推荐用于复杂度增加时)
流程:
- 手动将字符串添加到 String Catalog
- 通过类型安全的符号进行引用
- 组织到自定义表中
优点:控制力更强、类型安全、跨框架维护更轻松
缺点:需要预先规划字符串目录结构
// ✅ Generated symbols workflow
Text(.welcomeMessage)
| 工作流 | 最适合 | 权衡 |
|---|---|---|
| 字符串提取 | 新项目、简单应用、原型开发 | 自动提取,但对组织方式的控制较少 |
| 生成符号 | 大型应用、框架、多个团队 | 类型安全、组织更完善,但需要预先规划 |
在工作流之间重构
Xcode 26 支持在工作流之间转换,无需手动重写。
将字符串转换为符号
- 在代码中的字符串字面量上右键单击
- 选择 “Refactor > Convert Strings to Symbols”
- 预览所有受影响的位置
- 确认前自定义符号名称
- 应用到整个表或单个字符串
示例:
// Before
Text("Welcome to WWDC!", comment: "Main welcome message")
// After refactoring
Text(.welcomeToWWDC)
优点:
- 批量转换整个 String Catalog
- 应用前预览更改
- 无需重写代码即可保留本地化
实现检查清单
采用 Xcode 26 生成的符号后,请验证:
构建配置:
- 已启用“Generate String Catalog Symbols”构建设置
- 项目构建时不会出现“Cannot find 'symbolName' in scope”错误
- 清理后构建成功(Cmd+Shift+K,然后 Cmd+B)
字符串目录设置:
- 使用 + 按钮手动将字符串添加到目录中(而非自动提取)
- 符号名称遵循约定(驼峰命名,不含句点)
- 按功能组织自定义表(如果使用多个目录)
Swift Package 集成:
- 包中的所有
Text()和String(localized:)调用都使用bundle: #bundle - 在使用
#bundle的位置添加了 Import Foundation - 已分别测试包独立构建和作为依赖项时的构建
重构与迁移:
- 已在示例字符串上测试重构工具
- 应用更改前,预览显示了预期结果
- 过渡期间,旧的基于字符串的调用仍可正常使用
可选功能:
- 已在 Xcode Settings → Editing 中启用自动生成注释(可选)
- 已测试 AI 生成的注释是否准确
- XLIFF 导出内容包含自动生成的注释
测试:
- 符号在 SwiftUI 预览中可正确解析
- 本地化在所有支持的语言中均正常工作
- 应用可在最低支持的 iOS 版本上运行
资源
WWDC:2025-225、2023-10155、2022-10110
文档:/xcode/localization、/xcode/localizing-and-varying-text-with-a-string-catalog
技能:axiom-app-intents-ref、axiom-hig、axiom-accessibility-diag