news 2026/10/2 8:19:02

Mac Mouse Fix 的 XCStringsDummyApp:用哑元 Target 让 Xcode 导出不打包进 App 的 .xcstrings 文件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mac Mouse Fix 的 XCStringsDummyApp:用哑元 Target 让 Xcode 导出不打包进 App 的 .xcstrings 文件
  • 桌面应用
  • 系统编程

【免费下载链接】mac-mouse-fix

Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad!

项目地址:https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix
点击查看免费下载

导读

XCStringsDummyApp 是 Mac Mouse Fix 仓库中一个特殊的“哑元”工程 Target:它本身没有任何业务功能,存在的唯一目的,是让 Xcode 的本地化导出流程(Product > Export Localizations...与xcodebuild -exportLocalizations)能够导出那些被团队手动维护、又不想编译进任何 .app bundle的.xcstrings文件。阅读本文后,你将理解 Xcode 导出本地化的成员规则、这个哑元 Target 的完整搭建思路与关键构建设置,并能把同样的技巧复用到自己的多 Target 项目中。

一、为什么需要 XCStringsDummyApp:一个被 Xcode 规则逼出来的工程技巧

在 Mac Mouse Fix 项目中,本地化资源的管理方式很特别:开发团队手动维护.xcstrings文件(而非依赖 Xcode 自动抽取),这些文件统一存放在 Localization/Strings/ 下,例如Readme.xcstrings、Shared.xcstrings、Acknowledgements.xcstrings、Support/Support.xcstrings等。

问题出在 Xcode 的导出规则上。正如 XCStringsDummyApp/Readme.md 所记载的:

When exporting .xcstrings files into an .xcloc file usingProduct > Export Localizations...orxcodebuild -exportLocalizations, Xcode will only export .xcstrings files that are members of at least one target.

也就是说,Xcode 导出本地化(生成.xcloc本地化包)时,只会导出“至少属于一个 target 成员”的.xcstrings文件。一个没有被任何 target 引用的.xcstrings,即使躺在工程目录里,也会在导出时被静默忽略。

由此产生了两难:

  • 如果把这些.xcstrings添加为某个正常 App Target(如 Mac Mouse Fix 主应用)的成员,它们确实会被导出,但同时也会被编译进最终的.appbundle(Readme 中原话是 “It will be included in the compiled .app bundle (I think)”);
  • 但对其中一部分.xcstrings(例如用于生成 Markdown 帮助文档、由脚本或工具消费的字符串表),团队明确不希望它们出现在任何已编译的 App bundle里。

XCStringsDummyApp 正是为打破这个两难而存在的:把这类.xcstrings挂到 XCStringsDummyApp 这个专用 Target 名下,从而“骗过”Xcode 的成员检查,让它们可以被导出,却不会被装进任何真实产品 bundle。

二、XCStringsDummyApp 的组成:一个最小化的哑元工程

XCStringsDummyApp 目录下的文件全部是标准 macOS App 工程的最小骨架,逐一看一眼就知道它有多“空”:

文件作用
main.m仅调用NSApplicationMain(argc, argv),空白的@autoreleasepool占位,不初始化任何逻辑
AppDelegate.h空壳的NSApplicationDelegate协议实现声明
AppDelegate.mapplicationDidFinishLaunching:与applicationWillTerminate:均为空实现,仅返回YES支持安全恢复状态
MainMenu.xib承载NSMainNibFile所需的主菜单界面文件
XCStringsDummyApp-Info.plist手写的 Info.plist,只保留启动必需键
xcstrings_dummy_app.entitlements极简沙盒权限,仅开启 App Sandbox 与用户选择的只读文件访问

从 Mouse Fix.xcodeproj/project.pbxproj 可以看到这个 Target 的产品标识为com.nuebling.xcstrings-dummy-app(PRODUCT_BUNDLE_IDENTIFIER),产物为XCStringsDummyApp.app,部署目标MACOSX_DEPLOYMENT_TARGET = 15.0。

整个工程没有任何可运行的行为——它从不被用户真正使用,只是为了“挂载”字符串表而存在。

三、关键构建设置:两个开关决定导出行为的成败

哑元 Target 能否正常工作,取决于 pbxproj 中 Debug/Release 两套构建配置里的几个开关(见 project.pbxproj 的 XCStringsDummyApp 构建配置段):

1.LOCALIZATION_EXPORT_SUPPORTED = NO

这是最核心的开关。置为NO后,Xcode 在导出本地化时不会把这个 Target 的常规界面本地化资源(如MainMenu.xib对应的 strings)纳入.xcloc,从而保证哑元 Target 只贡献我们想导出的.xcstrings,不会夹带无关的本地化内容。

2.SWIFT_EMIT_LOC_STRINGS = YES

保留这个开关可以让 Xcode 在导出时仍然扫描并导出该 Target 名下挂载的字符串资源。它与LOCALIZATION_EXPORT_SUPPORTED = NO配合,形成“参与导出、但不导出界面资源”的精确行为。

此外该 Target 还启用了ENABLE_HARDENED_RUNTIME = YES、自动签名(CODE_SIGN_STYLE = Automatic)等常规设置,保证它在任何 scheme 下都能被正常编译——因为导出前 Xcode 会对涉及的 Target 执行构建。

四、为什么要用 Objective-C 写:构建时间是第一考量

Readme 中明确写道:

We made this objc for hopefully faster build times.

从源码看,这个结论很直观:main.m 与 AppDelegate.m 全部是纯 Objective-C 的空实现,不包含任何 Swift 代码。因为本地化导出通常要先构建参与导出的 Target,Swift 工程的编译(类型检查、模块生成、SwiftUI 预览编译等)成本远高于同规模的 ObjC 工程;用 ObjC 写一个“什么都不做”的哑元 App,能把导出前的构建时间压到最低。

对照整个仓库——Mac Mouse Fix 主应用和 Helper 都是 Swift/ObjC 混编的大型 Target(参见 App/ 与 Helper/ 目录),导出时若不得不构建它们,代价显然可观。哑元 Target 用纯 ObjC 就是针对这一开销的刻意优化。

五、注意事项:构建哑元 Target 时的三个坑

Readme 还记录了搭建过程中的实战经验(源自 mac-mouse-fix-website 仓库中同用途的xcode-dummy-target的教训,可参看 Various Notes/Localization Notes.md 了解本项目本地化工作流的更多背景):

  1. 必须禁用MainMenu.xib的本地化:否则该 nib 的本地化变体会作为资源被导出进.xcloc,污染导出产物;
  2. 必须手动添加 Info.plist:Readme 强调需要“manually add an Info.plist file and remove the localizable keys”。本项目正是这样做的——XCStringsDummyApp-Info.plist 只保留了CFBundleIdentifier、NSMainNibFile、NSPrincipalClass、CFBundleExecutable、CFBundlePackageType等启动必需键,并全部用$(...)构建设置变量取值,完全没有CFBundleDisplayName、CFBundleName这类可本地化键;
  3. 默认的本地化键会泄漏进.xcloc:若不按上面两步处理,Xcode 生成的本地化键会出现在.xcloc文件中,需要事后清理,不如一开始就规避。

六、已知问题:为什么导出时总是构建 Mac Mouse Fix 主 Target?

Readme 在 “Questions” 一节记录了一个截至 2025 年 9 月仍未解决的疑惑:

Product > Export Localizations...always builds the Mac Mouse Fix target, which is probably slowest part of the export. But why does it do that? Why not the other targets? Is there a build-setting to turn this off? Mysterious.

即:执行导出命令时,Xcode总是会构建 Mac Mouse Fix 主应用 Target——这通常是整个导出流程中最慢的部分。而哑元 Target 本身设计为纯 ObjC 空壳,恰恰是为了让“导出必须构建的 Target”尽量轻量。主 Target 被无故构建、而其他 Target(如 Helper)却不被构建的现象,从源码结构看暂时没有明显的构建设置可以解释,Readme 将其定性为 “Mysterious”。如果你在自建哑元 Target 时也遇到类似的“多余构建”,这属于 Xcode 行为层面的已知坑,值得单独排查。

七、总结:哑元 Target 模式的价值

XCStringsDummyApp 为 macOS 工程提供了一种可复制的本地化工程模式:

  • 把需要被 Xcode 导出、但不应进入产品 bundle的.xcstrings集中挂载到一个专用哑元 Target;
  • 用LOCALIZATION_EXPORT_SUPPORTED = NO屏蔽界面资源导出,用纯 ObjC 实现压缩构建成本;
  • 通过xcodebuild -exportLocalizations或 Xcode 菜单的Export Localizations...一次性产出包含这些字符串表的.xcloc。

对任何多 Target、且同时维护“编译型”与“非编译型”字符串表的 macOS 项目,这一模式都能直接迁移使用。相关源码与配置均可在仓库中按路径查阅:XCStringsDummyApp/Readme.md、XCStringsDummyApp/main.m、XCStringsDummyApp/XCStringsDummyApp-Info.plist、Mouse Fix.xcodeproj/project.pbxproj,以及被挂载导出的字符串表目录 Localization/Strings/。

  • 桌面应用
  • 系统编程

【免费下载链接】mac-mouse-fix

Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad!

项目地址:https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix
点击查看免费下载
上一篇:QMK Boardrun Classic 固件开发指南:正交立柱 60% 布局、Ergodox 键帽兼容与默认键位解析
下一篇:Epic Stack 部署实战指南:Fly.io 多区域部署、LiteFS 与 GitHub Actions CI/CD 全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 8:19:01

开源硬件学习的认知地图:四类渠道的层级路径与实操节奏

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 8:18:17

015-0601-numpy与pandas-numpy与pandas-series

环境搭建 Anaconda 什么是Anaconda Anaconda官网地址:Advance AI with Open Source | Anaconda 简单来说,Anaconda = Python + 包和环境管理器(Conda)+ 常用库 + 集成工具。它适合那些需要快速搭建数据科学或机器学习开发环境的用户。Anaconda和Python相当于是汽车和发…

作者头像 李华