用户最先看到的界面

直接分发 macOS 应用时,用户会下载 .dmg 文件并双击打开。那一刻,一个 Finder 窗口弹出。这个窗口就是用户与你的应用初次相遇的第一个界面。

一个制作精良的 .dmg 窗口通常长这样——背景铺着引导图示,左侧放着应用图标,右侧放着 Applications 文件夹快捷方式。用户将应用图标拖到 Applications 一侧即完成安装。这种"拖拽安装"是 macOS 独立开发者应用的事实标准安装体验。

这个窗口不会自动生成。背景图片、窗口大小、图标的位置和尺寸,都需要你亲自指定。本系列介绍如何设计这个 .dmg 窗口。

本系列以已完成签名、公证和 staple 的 .app 在手为前提,即处于分发前一步的应用。该过程在 Developer ID 直接分发系列中介绍过。.dmg 是直接分发(Developer ID)渠道的产出物,与 Mac App Store 渠道无关。

本系列将完成的内容

共两篇,最终你将具备以下内容:

  • (第 1 篇,本文) create-dmg 工具 + 仅含 .app 的暂存文件夹 + 背景图片准备
  • (第 2 篇) 窗口、图标和拖放目标的坐标设计 + 背景图片与坐标对齐 + 自动化

系列结束时,你应该已经准备好以下内容:

  • 仅隔离存放 .app 的暂存文件夹
  • 符合 @2x 视网膜屏惯例且 DPI 已规范化的背景图片
  • 窗口大小和图标位置均以坐标确定的 create-dmg 命令
  • 可在每次发布时原样复用的形态

示例应用 — FocusTimer

与前几个系列相同,以虚构的 macOS 应用 FocusTimer(管理专注时间的简单计时器应用)为例。FocusTimer、路径、坐标值等均为示例,实际使用时请替换为你自己的应用。

什么是 DMG

DMG(.dmg是 macOS 的磁盘镜像 (disk image) 文件。可以将其理解为一个"虚拟磁盘"——单个文件内部完整包含了文件夹和文件结构。用户双击 .dmg 后,macOS 会像挂载磁盘一样将其挂载,其内容以 Finder 窗口的形式打开。

在应用分发中使用 DMG 的原因:

  • 应用(.app)实际上是一个文件夹。将文件夹直接发布到互联网比较困难,但用 DMG 包裹后就变成了单个文件
  • 可以在 DMG 窗口内放入 Applications 文件夹快捷方式,引导用户一次拖拽即可完成安装
  • 可以设计窗口的外观——背景、图标位置等,让安装体验更加简洁。

工具 — create-dmg

手动制作 DMG 需要经过多个步骤:用 hdiutil 创建镜像、挂载、用 AppleScript 操作 Finder 窗口放置图标,再卸载等。繁琐且容易出错。

create-dmg 是将这一流程浓缩为单条命令的开源工具。将背景图片、窗口大小、图标坐标作为选项传入,它就会生成完成的 .dmg

Developer ID 直接分发系列第 1 篇中安装前置工具时已经安装过了。若尚未安装,请通过 Homebrew 安装:

brew install create-dmg

名为 create-dmg 的项目有两个。本文使用的是通过 Homebrew 安装的命令行工具(create-dmg/create-dmg)。请勿与选项名称不同的另一个项目混淆。

第 1 步 — 仅含 .app 的暂存文件夹

DMG 中应该整洁地只放一个应用图标。然而构建和导出应用后,结果文件夹中除了 .app 之外,还有 DistributionSummary.plist、打包日志等副产物文件。直接将这个文件夹制作成 DMG,副产物也会暴露在窗口中。

因此,需要将 .app 单独复制到空文件夹中隔离,以该文件夹作为制作 DMG 的原料。这个隔离用文件夹通常称为暂存 (staging) 文件夹

# 将 .app 单独复制到空文件夹中,避免与副产物混在一起
DMG_STAGE="build/dmg-stage"
rm -rf "$DMG_STAGE"
mkdir -p "$DMG_STAGE"
cp -R "build/export/FocusTimer.app" "$DMG_STAGE/"

现在 build/dmg-stage/ 中只有 FocusTimer.app 一个文件。制作 DMG 时将 create-dmg 指向此文件夹,窗口中就会整洁地只显示应用图标。(Applications 文件夹快捷方式将在第 2 篇中通过 create-dmg 选项自动生成。)

第 2 步 — 准备背景图片

DMG 窗口设计的核心是背景图片。这里是最容易卡住的地方,我们一步步来看。

画布尺寸 — 为何是 1200×800

第 2 篇中会向 create-dmg 传递 --window-size 600 400 来设定 DMG 窗口大小。此时 600400 的单位不是像素,而是点 (point)。点是 macOS 使用的逻辑坐标单位。

在视网膜屏 (Retina) 显示器上,1 点对应 2 个像素。因此,要完整清晰地填满 600×400 点的窗口,背景图片必须是其 2 倍大小,即 1200×800 像素。这就是 @2x(2 倍分辨率)惯例

总结:窗口是 600×400 点,背景图片是 1200×800 像素。 这个 2 倍关系在第 2 篇设定坐标时还会再次用到,非常重要。

背景中绘制什么

这里纠正一个常见误解:背景图片中不要绘制应用图标或 Applications 文件夹图标。 这些图标由 create-dmg 作为实际文件放置在窗口上(第 2 篇)。

背景图片中只放装饰和引导元素

  • 从应用图标指向 Applications 文件夹的箭头 — 最常见的设计,引导用户的视线和手"向这个方向拖拽"。
  • 如有需要,可加上"拖到此处"等简短引导文字
  • 品牌色或淡淡的背景纹理

也就是说,背景图片是**“留空图标放置位,只绘制连接两者的引导线的图”**。左右各留出图标将要占用的位置(第 2 篇中各为 100 点 = 200 像素),在中间放置箭头。

关键陷阱 — DPI

背景图片中最常踩到的陷阱是 DPI(每英寸像素数)

用图像编辑器导出 PNG 时,文件中除了像素数(1200×800)之外,还会存储 DPI 值。Finder 在绘制 DMG 背景时会读取这个 DPI,反算出"该图片是多少的尺寸"。计算大致如下:

点尺寸 = 像素数 ÷ (DPI ÷ 72)
  • 若 DPI 为 1441200 ÷ (144 ÷ 72) = 1200 ÷ 2 = 600 点。恰好填满窗口(600 点)。✅
  • 然而,某些图像编辑器(如 Pixelmator Pro)导出时会嵌入任意 DPI 值(如 338)。若 DPI 为 338:1200 ÷ (338 ÷ 72)256 点。比窗口(600 点)小得多,背景就会缩小成一团,塞在窗口左上角。❌

像素数同样是 1200×800,却因为一个 DPI 值导致背景显示异常。第一次遇到时真的很难找到原因。

解决方案是将导出 PNG 的 DPI 强制统一为 144。macOS 内置的 sips 命令一行即可搞定:

sips -s dpiWidth 144 -s dpiHeight 144 dmg-background.png

执行这一行后,无论编辑器嵌入了何种 DPI,都会被设为 144,1200×800 像素将被准确解读为 600×400 点。

要点 — 背景图片 ① 制作为 1200×800 像素,② 导出后sips 将 DPI 规范化为 144。遵守这两点就能避开 DPI 陷阱。

第 1 篇小结

跟到这里,你现在已经准备好以下内容:

  • ✅ 安装了 create-dmg 工具,并了解其作用
  • ✅ 仅隔离存放 .app 的暂存文件夹(build/dmg-stage/
  • ✅ 以 1200×800 像素制作且 DPI 已规范化为 144 的背景图片

素材已经准备就绪。但还没有一个窗口来显示背景图片并放置图标。窗口要多大、应用图标和 Applications 快捷方式各放在哪里——这一切都由传给 create-dmg坐标来决定。

下一篇将逐一设计这些坐标,介绍如何让背景像素坐标与窗口点坐标对齐以使背景中的箭头恰好落在两个图标之间,以及如何自动化整个流程以在每次发布时复用。