← 所有文章

Xcode 27.1 beta:把应用放进 iPhone Duo 模拟器

Xcode 27.1 beta(27A9269)于 2026 年 9 月 18 日星期五发布,带来第一个 iOS 27.1 SDK,以及一个供模拟器使用的 iPhone Duo 设备类型,距 Xcode 27.0 只有四天。这个 SDK 收齐了 Apple 适配指南点名的全部 iPhone Duo API;设备类型的配置文件把两块显示屏定义为 3 倍缩放下的 1398 × 2034 像素和 2007 × 2853 像素,也就是 466 × 678 点与 669 × 951 点;模拟器运行时则是单独的下载,由 Xcode 按需取回。Apple 自己的说明列出了模拟器目前还做不到的三件事。我把一个探针应用放进 Device Hub 的三种姿态里跑:合上时它落在 466 × 678 点的屏幕上,展开时落在 951 × 669 点的屏幕上,展开状态下两个方向都是 regular;任何姿态下都没有报告保留区域;而当应用已经在内屏上时,UIScreen.main 答的仍然是外屏。12456 {.answer-block}

TL;DR

  • 日期与构建版本。 Apple 的 Releases 信息源把 Xcode 27.1 beta(27A9269)标在 9 月 18 日星期五。xcodebuild -version 打印 Xcode 27.1Build version 27A9269;iPhoneOS 与 iPhoneSimulator 两个 SDK 都自称 iOS 27.1、构建版本 24A94403;Swift 编译器报出的版本字符串 swiftlang-6.4.0.34.1 与 Xcode 27.0 相同,链接器的 ld-27037.1 也一样。xip 为 2,027,292,809 字节,展开后的应用 3.6 GiB,并且是装在 Xcode 27.0 旁边,不会替换它。14
  • Duo API 已经在 SDK 里。 我在 9 月 17 日那次检查中没能在 27.0 SDK 里找到的十个名字,在 27.1 SDK 中全部出现,其中包括 SwiftUICore 的 ArrangementViewreservedRegions(kind:options:layoutDirectionBehavior:)、SwiftUI 的 toolbarVerticalBehavior(_:),以及 UIKit 的 UIArrangementViewControllerpreferredVerticalBarBehaviorverticalBarEdge。SwiftUI 给它们标的是 @available(anyAppleOS 27.1, *);UIKit 的头文件给 arrangement 控制器和保留区域方法标的是 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1)),比文档页面列出的多两个平台。4
  • 模拟器的配置文件把屏幕尺寸写了下来。 iPhone Duo 设备类型(iPhone19,4,产品类 V68,型号 A3447)定义了两块内建显示屏:primary 为 1398 × 2034 像素、缩放 3,primary-1 为 2007 × 2853 像素、缩放 3,原生方向 270。各除以 3 就是 466 × 678 点和 669 × 951 点,其中内屏的数字,正是我那篇 Duo 开发者文章在 9 月 10 日从 App Store Connect 截图尺寸推算出来的值。配置文件要求运行时为 27.1 或更高。5
  • 把真实应用放上去会怎样。 Device Hub 提供三种姿态:Closed(合上)、Book(半开)、Open(展开),另加 Rotate Right(向右旋转)。Closed 时探针拿到的是外屏:466 × 678 点,宽度 compact,split 形式的 arrangement 上下堆叠。Open 时它拿到内屏:原生横向的 951 × 669 点,两个尺寸类别都是 regular,左右两侧各 34 的安全区域内边距,split 形式的 arrangement 左右并排;旋转之后是宽 669、高 951,两个方向依然都是 regular。Book 给应用的几何与 Open 完全相同。每一种姿态下,reservedRegions 都什么也没返回,即便把非活动区域一并算上也是如此;toolbarVerticalEdge 始终是 nil;工具栏横着画;而应用在内屏上时,UIScreen.main.bounds 一直报告 466 × 678。6
  • 这个 beta 还做不到什么。 Apple 的说明写道:“Initial Simulator launch can take several minutes.”(187708500)、“StandBy is unavailable in the iPhone Duo Simulator runtime.”(187708663),以及“Running and debugging most app extensions is unavailable in the iPhone Duo Simulator runtime.”(187708767)。如果你的应用同时发往 Mac,还要再加上两条 Mac Catalyst 的 Known Issues。另外还有一件 Apple 没有列出的事:运行时下载在我第一次尝试时以 Download failed. 失败,重试才成功。23

这个 beta 里有什么?

Apple 的 Releases 信息源把“Xcode 27.1 beta (27A9269)”列在 9 月 18 日星期五上午 10 点(太平洋时间),当天下午还有一条“TestFlight Update”;App Store Connect 同日的发行说明写道:“You can now submit apps built with Xcode 27.1 beta using the SDK for iOS 27.1 beta or iPadOS 27.1 beta for internal and external testing.”1 发行说明的 Overview 则点名了 SDK 的清单:“Xcode 27.1 beta includes Swift 6.4 and SDKs for iOS 27.1, iPadOS 27, tvOS 27, watchOS 27, macOS 27, and visionOS 27. Xcode 27.1 beta supports on-device debugging in iOS 17 and later, tvOS 17 and later, watchOS 10 and later, and visionOS. Xcode 27.1 beta requires a Mac running macOS Tahoe 26.6 or later.”2 这份清单要照字面读:停在 27.1 的平台只有 iOS,SDK 自己的 SDKSettings.plist 报告的版本也是 27.1,而 App Store Connect 把同一个 SDK 叫作“iPadOS 27.1 beta”,这道别扭之处由那篇 Xcode 27 的文章一路带着。

下载比版本号给人的印象要小。xip 为 2,027,292,809 字节,由 Apple 的 Software Update 证书签名,展开后是一个 3.6 GiB 的应用,与 Xcode 27.0 同样大小;就命令行工作而言,用 xip --expand 展开到一个文件夹、重命名为 /Applications/Xcode-27.1-beta.app、再把 DEVELOPER_DIR 指过去,安装就到此为止。随后在 beta 下的第一次 xcodebuild 调用自行花了大约两分钟,安装随包附带的 CoreTypes.pkgXcodeSystemResources.pkg,也就是 xcodebuild -runFirstLaunch 会显式执行的那一步;而其中第二个包,正是把 iPhone Duo 设备类型安放到位的那一个。4 应用里没有的,是模拟器运行时。beta 找到了这台 Mac 上已有的各个 iOS 运行时,其中有 27.0,却没有 27.1;在 beta 下运行 xcodebuild -downloadPlatform iOS,它把缺失的那块称为“iOS 27.1 Simulator (24A94401)”,并通过 Apple 的 mobile-asset 服务以 cryptex 磁盘映像的形式取回,而开发者下载页面上的磁盘映像本身还停在 iOS 18.2 Simulator Runtime。34 第一次尝试以 DVTDownloadable: Download FailedError Domain=DVTDownloadableErrorDomain Code=41 "Download failed." 告终;第二次加上 -buildVersion 24A94401,把运行时报告为 7.85 GB,顺利跑完,随后 simctl list runtimes 里就列出了“iOS 27.1 (27.1 - 24A94401)”。磁盘空间要预留够:这个运行时是 Xcode 下载量的四倍。3

运行 iOS 27.1 beta 的 iPhone Duo 模拟器首次启动时的外屏:深色主屏幕,左上角是设置图标,右侧边缘竖向排着时钟与 Wi-Fi 状态,右边是一块 Dock 方块,右下角是搜索按钮

iPhone Duo 模拟器首次启动时的外屏,1398 × 2034 像素:状态区沿右侧边缘竖着排列,正是 Apple 的 Human Interface Guidelines 在 iPhone Duo 上安放 Dynamic Island 与状态栏的那一侧。10

27.1 SDK 里有 Duo API 吗?

9 月 17 日,我按 Apple 那份“Preparing your app for iPhone Duo”指南里的名字去搜 iOS 27.0 SDK,专属于这台设备的十个一个也没找到。同样的搜索、同样的做法,也就是对模块接口和头文件做一次朴素的文本搜索,换到 27.1 SDK 上就全都找得到。表中的行是搜索用的子串:其中七行承载了十个名字里的九个,因为两个 reservedRegions 方法共用一行,两个 axisBehavior 成员也共用一行;另外三行是这些名字背后的类型,即 ReservedRegion、对应 toolbarVerticalBehavior(_:)ToolbarVerticalBehavior,以及对应 preferredVerticalBarBehaviorUIVerticalBarBehavior4

搜索的子串 SwiftUICore 接口 SwiftUI 接口 UIKit 接口 UIKit 头文件
ArrangementView 45 0 19 4 个文件
UIArrangementViewController 0 0 19 4 个文件
ReservedRegion 16 0 15 3 个文件
reservedRegions 2 0 5 1 个文件
ToolbarVerticalBehavior 0 5 0 0
UIVerticalBarBehavior 0 0 0 1 个文件
verticalBarEdge 0 0 0 1 个文件
toolbarVerticalEdge 1 0 0 0
axisBehavior 0 2 0 1 个文件
preferredVerticalBarBehavior 0 0 0 1 个文件

这张表里有两处细节会影响你怎么写代码。其一,SwiftUI 的那些类型住在 SwiftUICore 里,而这个模块由 import SwiftUI 再导出,所以普通的 import 就能找到它们;其二,可用性属性在平台范围上与文档不一致。SwiftUICore 接口声明 ArrangementView、SwiftUI 接口声明 toolbarVerticalBehavior(_:),两者都在 @available(anyAppleOS 27.1, *) 之下,而 anyAppleOS 是 Apple 用来表示“该版本的所有平台”的简写;与此同时,UIArrangementViewController.h 以及 UIView.h 里的 reservedRegionsOfKind: 方法带的是 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1)) 加上 API_UNAVAILABLE(watchos);在 UIVerticalBarEdge.h 中,枚举和 verticalBarEdge 特性带着同一组标注,而 Leading 与 Trailing 两个成员带的是 API_AVAILABLE(ios(27.1)) API_UNAVAILABLE(visionos) API_UNAVAILABLE(watchos, tvos)。Apple 这五个名字的文档页面,都只列出 iOS 27.1 和 iPadOS 27.1,并标记为 beta。47 照着 iOS 写,其余的让编译器告诉你。

指南用到的名字里,已经存在于 27.0 SDK 的那三个没有变化:presentationPlacement(_:) 仍在 @available(anyAppleOS 27.0, *) 之下,backgroundExtensionEffect() 从 iOS 26 起就一直在;至于指南点名的两个 ToolbarItemPlacement 成员,topBarPinnedTrailing@available(iOS 27.0, visionOS 27.0, *) 之下,而 cancellationAction 除了类型本身的可用性之外没有另行标注。4

模拟器的配置文件怎么说这两块屏?

Apple 随 beta 装上的设备类型 iPhone Duo.simdevicetype,是 /Library/Developer/CoreSimulator/Profiles/DeviceTypes 下一个朴素的 bundle,而它的两个属性列表回答了规格表留着没说的问题。5

profile.plist 给出身份:型号标识符 iPhone19,4,产品类 V68,别名 com.apple.CoreSimulator.SimDeviceType.V68minRuntimeVersion 为 27.1,还有一条规则,让 27.1 及以上的运行时默认创建这台设备。capabilities.plist 给出硬件:型号 A3447,HomeButtonType 为 2,DeviceSupportsDynamicIsland 为 true,DeviceSupportsEnhancedMultitasking 为 false,IsLargeFormatPhone 为 true,CompatibleDeviceFallbackiPhone18,3,设备圆角半径 59,以及一个包含两个内建条目和三个虚拟条目的 displays 数组。5

配置文件中的显示屏 像素 缩放 原生方向 圆角半径 色彩空间
primary(“LCD”,屏幕 1) 1398 × 2034 3 466 × 678 0 8、59、8、59 P3
primary-1(“LCD-1”,屏幕 3) 2007 × 2853 3 669 × 951 270 四角均为 55 sRGB

第一行是外屏,与 Apple 的规格表逐像素吻合。第二行是内屏,而它的像素数是 App Store Connect 的截图尺寸 2007 × 2853,而非面板自身的 1878 × 2670:模拟器把内屏按 3 倍缩放渲染成 669 × 951 点,这正是那篇 Duo 开发者文章在 9 月 10 日做过、并明确标注为推断的那道算术。如今 Apple 自己的配置文件带上了这个数字。270 度的原生方向说明内屏是原生横向的,设备展开时宽 951 点、高 669 点,这与 Apple 给出的展开状态尺寸一致。剩下两个数字属于模拟器而非硬件:两块屏都写着每英寸 460 像素、60 Hz,而规格表给内屏面板的是 430 ppi,所以请把 hdpi 当作占位值。5

配置文件还带来了形状。每块显示屏都引用一个帧缓冲遮罩,也就是一份描述可见区域的 PDF。外屏的遮罩四角并不对称,配置文件里的值是一条长边 8、另一条长边 59;依我的判断,半径小的那一侧就是 Apple 设计指南所说的、与中间铰链相接的那一侧。内屏的遮罩则是一个普通的圆角矩形,用的就是配置文件里 55 的圆角值,并且没有为前置摄像头留挖空;也就是说,摄像头造成的遮挡来自运行时的保留区域 API,而不是帧缓冲的形状。510

模拟器里能看到什么?

设备以合上的状态启动。首次启动时外屏显示主屏幕,内屏的帧缓冲亮着却是黑的;simctl io enumerate 会按配置文件里的名字把两块内建屏幕都列出来,primary 为 1398 × 2034,primary-1 为 2007 × 2853,与那些常见的虚拟屏并排。6 我装了一个单文件的 SwiftUI 探针,它读取几何信息、尺寸类别、toolbarVerticalEdge 环境值,以及带 includeInactive 的两类保留区域,用三种样式各包一个 ArrangementView,并在导航工具栏里放了六个项目。6

iPhone Duo 模拟器外屏上的探针应用:右上角工具栏依次是分享图标、省略号溢出按钮和对勾,读数为尺寸 386 × 510 点、尺寸类别 compact 与 regular、toolbarVerticalEdge 为 nil、divisions 0、occlusions 0,split 形式的 arrangement 中主视图在次视图上方,右侧边缘竖排着时钟与 Wi-Fi 状态

外屏上的探针,Closed 姿态:466 × 678 点,宽度 compact,split 形式的 arrangement 上下堆叠,工具栏横向。

Closed 时,探针报告的就是一台紧凑 iPhone 会报告的东西。UIScreen.main.bounds 是缩放 3 下的 466 × 678 点,尺寸类别为宽 compact、高 regular,toolbarVerticalEdge 为 nil,UIKit 的 verticalBarEdge 特性读作原始值 0,两次保留区域查询即便把非活动区域算上也都返回空数组,也就是说合上的姿态不会向应用暴露折痕,也不会暴露摄像头。导航堆栈内部的 GeometryReader 量到 386 × 510 点,安全区域内边距是顶部 134、底部 34,两侧为零;依我的判断,系统留下的那 80 点宽度就是右侧那条承载状态区的竖条。split 形式的 arrangement 把主视图放在次视图之上,也就是 Apple 指南描述的高大于宽的情形;工具栏横着画在顶部,分享按钮和对勾形状的完成按钮挨着溢出按钮,四个次级操作不在栏上,从它们的 placement 看是收进了菜单里。67

姿态住在 Device Hub 里。选中这台 Duo 设备后,它的窗口会把 Rotate Right、Closed、Book 和 Open 显示为辅助功能 API 可以按下的按钮,本节余下的内容就是这么驱动出来的。6

Open 会把应用挪到内屏上,并采用内屏原生的横向方向。探针报告宽 regular、高 regular,GeometryReader 量到 803 × 515 点,安全区域内边距是顶部 134、两侧各 34、底部 20,宽度上同样少了 80 点,和合上时一样;依我的判断还是那条竖条,只是这次落在一块 951 点宽的屏幕右侧,状态区就在其中。split 形式的 arrangement 把主视图和次视图左右并排,也就是 Apple 指南里宽大于高的情形;工具栏横着画在右上角,同样是分享和完成挨着溢出按钮,四个次级操作仍不在栏上。6

Open 姿态下、横向的 iPhone Duo 模拟器内屏上的探针应用:尺寸 803 × 515 点,尺寸类别 regular 与 regular,toolbarVerticalEdge 为 nil,divisions 0、occlusions 0,split 形式的 arrangement 中主视图与次视图左右并排,工具栏在右上角,右侧边缘一条黑色竖条里是时钟与 Wi-Fi 状态

Open 姿态,内屏,2853 × 2007 像素:两个方向都是 regular,split 形式的 arrangement 左右并排,竖条在右侧。

Rotate Right 把内屏转成竖向。此时探针量到 669 × 703 点,两个方向都是 regular,内边距为顶部 134、底部 34,两侧为零;依我的判断,那条 80 点的竖条挪到了顶边,状态区如今落在那里的一条黑带上,而即便容器已经变得高大于宽,split 形式的 arrangement 依旧左右并排。6

旋转为竖向的 iPhone Duo 模拟器内屏上的探针应用:尺寸 669 × 703 点,尺寸类别 regular 与 regular,split 形式的 arrangement 仍然左右并排,顶部横贯一条黑带,里面是时钟与 Wi-Fi 状态

旋转后的内屏:宽 669 点,两个方向依然都是 regular,竖条横在顶部。

Book 这种半折的姿态,本该是保留区域 API 大显身手的地方,可在这个 beta 里,它对我的探针并没有这么做。前台没有应用时按下 Book,内屏显示的是主屏幕;重新启动后,探针报出来的与 Open 时一模一样:803 × 515 点,两个方向都是 regular,把非活动区域算上也仍是 divisions 0、occlusions 0,SwiftUI 和 UIKit 都是如此。合上的姿态同样报 0。我没有找到任何一种姿态能让 reservedRegions 返回折痕或摄像头,所以一套随折痕自适应的布局,是这个 beta 的模拟器没能让我看到的东西;Apple 的指南把分割变为活动的时机描述为“when iPhone Duo is partially open,”(当 iPhone Duo 半开时),至于这究竟是 beta 的缺口还是探针的缺口,那是留给下一个 beta 的问题。67

还有两件事在每种姿态下都成立。工具栏从未竖着画过:toolbarVerticalEdge 在 SwiftUI 里是 nil,verticalBarEdge 在 UIKit 里读作原始值 0,合上、展开、旋转皆然,所以 Apple 指南描述的竖栏,在这个 beta 里并没有出现在导航堆栈的工具栏上。另外,当应用已经在内屏上时,UIScreen.main.bounds 答的是 466 × 678 点,也就是外屏,这正是 Apple 指南提醒要把布局计算“based on your scene or containing view’s bounds rather than screen dimensions”(基于场景或所在视图的 bounds,而不是屏幕尺寸)时所警告的陷阱:主屏幕并不是你正身处的那块屏幕。探针构建时,编译器其实已经在说 'main' was deprecated in iOS 26.0,而这台设备就是原因所在。67

通往其他姿态的路,有一条是走不通的。simctl io screenConfig 可以把某块屏幕断电,但在内屏亮着的情况下把外屏断电,并不会让手机展开;它反而让模拟器的 system shell 崩溃,随后的 simctl launch 以“The system shell probably crashed.”失败,只能重启。姿态住在 Device Hub 的窗口里。6

这个 beta 还做不到什么

Apple 在 beta 自己的说明中,于 Simulator、Known Issues 下列了三条限制:“Initial Simulator launch can take several minutes.”(187708500)、“StandBy is unavailable in the iPhone Duo Simulator runtime.”(187708663),以及“Running and debugging most app extensions is unavailable in the iPhone Duo Simulator runtime.”(187708767)。2 其中 StandBy 那条,对于做了相应小组件或实时活动的人很要紧:Apple 的发布稿说这台手机“enters StandBy on either the outer or inner display”(在外屏或内屏上进入 StandBy),并把它称作“hub for widgets”(小组件的中枢);那里会出现什么,那篇 Duo 开发者文章已经讲过。在后续 beta 解除这条限制之前,这台设备上的 StandBy 只能到真机上去验。11

另外两条位于 Mac Catalyst、Known Issues 之下,会咬到任何既采用这些 API、又要为 Mac 构建的应用:“Projects that use APIs specific to iOS 27.1 show compile errors when building for Mac Catalyst (“undeclared identifier”, “not found”, “has no member”, “cannot find”, etc). (185924957)”,Apple 给的绕行办法是在 Swift 中用 #if !targetEnvironment(macCatalyst)、在 Objective-C 中用 #if !TARGET_OS_MACCATALYST;以及“Projects that target iOS 27.1 show no Mac Catalyst run destination available. (187046347)”,绕行办法是“Add a Mac Catalyst 27.0 minimum deployment in target settings.”。2 Xcode 27.2 beta 的说明又从另一个方向补上第三条:“macOS, watchOS, tvOS, and visionOS SDKs in Xcode 27.2 incorrectly report 27.1 as a valid deployment target,”以及“Mac Catalyst builds with a 27.1 or 27.2 deployment target may be unable to use newly introduced API.” (187160501)。8

这周我会做什么

  1. 把 beta 装在 Xcode 27.0 旁边,而不是覆盖它:展开 xip、重命名应用,再把 DEVELOPER_DIR 指向它用于命令行构建。beta 的说明里没有任何一项改动 27.0 的工具链,编译器和链接器的版本字符串也完全相同。4
  2. 在真正需要之前就开始下载运行时:在 beta 下执行 xcodebuild -downloadPlatform iOS,失败就重试。正是这个运行时让 iPhone Duo 设备类型可以启动,而且 Apple 还警告说首次启动要再花上几分钟。23
  3. 带上 Mac Catalyst 目标,对着 27.1 SDK 构建一次,并在决定是用 #if !targetEnvironment(macCatalyst) 把新 API 围起来、还是把 Catalyst 最低部署版本提到 27.0 之前,先读一读 Apple 点名的那两条诊断。2
  4. 把配置文件里的数字当作预览和测试的尺寸:合上 466 × 678 点,展开 669 × 951 点,内屏原生横向。beta 的 Previews 说明还在画布的覆盖选择器里加了一个 Display 分组,“for previewing content on a device’s alternative display.”(用于在设备的另一块显示屏上预览内容)(182598534)25
  5. 开发期间按姿态记录保留区域:文档说,带 .includeInactivereservedRegions(kind:options:layoutDirectionBehavior:) 会把折痕和摄像头作为可能处于活动或非活动状态的 ReservedRegion 值返回;在这个 beta 里每种姿态都什么也没返回,所以在 onChange(of: proxy.size) 里加一行日志,就能知道某个姿态是从哪一刻开始报告它们的。67

常见问题

Xcode 27.1 beta 里有 iPhone Duo 模拟器吗?

有。这个 beta 会装上一个 iPhone Duo 设备类型,即 com.apple.CoreSimulator.SimDeviceType.iPhone-Duo,它的配置文件要求一个 iOS 27.1 运行时,而该运行时由 Xcode 通过 xcodebuild -downloadPlatform iOS 单独下载。Apple 的说明提醒,首次启动“can take several minutes”(可能要花上几分钟),并且在该运行时中无法使用 StandBy 和大多数 App Extension。235

怎样把 Xcode 27.1 beta 装在 Xcode 27 旁边?

xip --expand 展开 xip,把得到的应用移成一个带版本号的名字,例如 /Applications/Xcode-27.1-beta.app,再为 xcodebuildxcrunswiftcDEVELOPER_DIR 设到它的 Contents/Developer 文件夹。这个 beta 要求 macOS Tahoe 26.6 或更高,与 Xcode 27.0 的门槛相同。24

iPhone Duo 内屏按点算是多大?

669 × 951 点。模拟器的设备配置文件把内屏定义为缩放 3 下的 2007 × 2853 像素,且原生方向为横向;外屏则是缩放 3 下的 1398 × 2034 像素,合 466 × 678 点。5

Xcode 27.1 beta 会改动 iOS 27.0 SDK 或 Xcode 27 的工具链吗?

不会。Swift 编译器和链接器报出的版本字符串与 Xcode 27.0 相同,而这个 beta 的发行说明只有 Mac Catalyst、Previews 和 Simulator 三节,没有一节触及工具链。iOS 27.1 SDK 是新增的,在设备端和模拟器端的 SDK 中都标识为构建版本 24A94403。24

iPhone Duo 什么时候发售,运行什么系统?

10 月 23 日,运行 iOS 27.1,依据是 Apple 9 月 16 日的新闻稿:“When iPhone Duo becomes available on October 23, it will run iOS 27.1.”9

参考来源


  1. Apple,Releases,2026 年 9 月 19 日获取的 RSS 信息源:“Xcode 27.1 beta (27A9269)”标注为 Fri, 18 Sep 2026 10:00:00 PDT,“TestFlight Update”标注为 Fri, 18 Sep 2026 14:00:00 PDT。Apple,App Store Connect 发行说明,2026 年 9 月 18 日,TestFlight 更新,全文引用。 

  2. Apple,Xcode 27.1 Beta Release Notes,2026 年 9 月 19 日通过文档 JSON 端点获取:Overview,引用;Mac Catalyst、Known Issues 185924957 和 187046347 连同其绕行办法,引用;Previews、New Features 182598534,引用;Simulator、Known Issues 187708500、187708663 和 187708767,引用。这份说明再无其他章节。 

  3. 作者在 macOS 26.6.2(25G83)上于 2026 年 9 月 19 日进行的运行时下载,DEVELOPER_DIR 指向 Xcode 27.1 beta:xcodebuild -downloadPlatform iOS 对已安装的 27.0 运行时打印“iOS is already downloaded.”,随后打印“Downloading iOS 27.1 Simulator (24A94401) (arm64)”,接着是 DVTDownloadable: Download Failed. Downloadable: DVTDownloadable(identifier: 0a4e7582-0061-5907-bea9-fe234c1f9392, version: 27.1.0.1, category: simulator, contentType: cryptexDiskImage, downloadMethod: mobileAsset, platform: com.apple.platform.iphoneos)Error Domain=DVTDownloadableErrorDomain Code=41 "Download failed.";重试的 xcodebuild -downloadPlatform iOS -buildVersion 24A94401 打印“Downloading iOS 27.1 Simulator (24A94401) (arm64): 0.0% (66 kB of 7.85 GB)”并完成,此后 xcrun simctl list runtimes 列出“iOS 27.1 (27.1 - 24A94401) - com.apple.CoreSimulator.SimRuntime.iOS-27-1”。同日以登录状态在 Apple 开发者下载页面搜索“Simulator Runtime”,列出的磁盘映像最新不过 iOS 18.2 Simulator Runtime。 

  4. 作者于 2026 年 9 月 19 日对 /Applications/Xcode-27.1-beta.app 的检查:xcodebuild -version 打印 Xcode 27.1Build version 27A9269xcrun --sdk iphoneos --show-sdk-versionxcrun --sdk iphonesimulator --show-sdk-version 都打印 27.1;两个 SDK 的 SystemVersion.plist 都带有 ProductBuildVersion 24A94403 和 ProductVersion 27.1;xcrun swift --version 打印 Apple Swift version 6.4 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)xcrun ld -v 打印 ld-27037.1,与同一台 Mac 上 Xcode 27.0(27A266a)打印的版本字符串相同。Xcode_27.1_beta.xip 为 2,027,292,809 字节;pkgutil --check-signature 报告为“signed Apple Software”,证书链来自 Software Update;对展开后应用执行 du -sk 得到 3,813,336 KB,而展开在 /Applications/Xcode-27.app 的 Xcode 27.0(27A266a)为 3,804,188 KB。名称计数来自对 iPhoneOS SDK 中 SwiftUICore.swiftmodule/arm64e-apple-ios.swiftinterfaceSwiftUI.swiftmodule/arm64e-apple-ios.swiftinterfaceUIKit.swiftmodule/arm64e-apple-ios.swiftinterfacegrep -c,以及对 UIKit.framework/Headers 全目录的 grep -rl 文件数;可用性属性同样读自这些文件:SwiftUICore 接口中 public struct ArrangementView< 之上,以及 SwiftUI 接口中声明 func toolbarVerticalBehavior 的那个 extension SwiftUICore.View 之上,都是 @available(anyAppleOS 27.1, *)UIArrangementViewController.hUIView.h 中两处 reservedRegionsOfKind: 声明,以及 UIVerticalBarEdge 枚举和 verticalBarEdge 特性上,都是 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1)) 后接 API_UNAVAILABLE(watchos),而其 UIVerticalBarEdgeLeadingUIVerticalBarEdgeTrailing 成员上是 API_AVAILABLE(ios(27.1)) API_UNAVAILABLE(visionos) API_UNAVAILABLE(watchos, tvos)func presentationPlacement 之上是 @available(anyAppleOS 27.0, *)public static let topBarPinnedTrailing 之上是 @available(iOS 27.0, visionOS 27.0, *)public static let cancellationAction 之上没有属性。关于首次启动:在 beta 的 DEVELOPER_DIR 下第一次执行的 xcodebuild -version 超过了两分钟的超时;/var/log/install.log 记录 xcodebuild 于 9 月 19 日 16:01:54 排入一次 PackageKit 安装,从 Xcode-27.1-beta.app/Contents/Resources/Packages 解出 CoreTypes.pkgXcodeSystemResources.pkg,并于 16:03:04 结束;此后 xcodebuild -checkFirstLaunchStatus 返回 0。 

  5. /Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone Duo.simdevicetype,由 Xcode 27.1 beta 安装,于 2026 年 9 月 19 日用 plutil -convert xml1 读取。profile.plistmodelIdentifier iPhone19,4,productClass V68,aliases com.apple.CoreSimulator.SimDeviceType.V68,minRuntimeVersion 27.1,createByDefaultForRuntimeVersions 的 versionMin 27.1。capabilities.plistModelNumber A3447,ThinningProductType iPhone19,4,CompatibleDeviceFallback iPhone18,3,DeviceCornerRadius 59,HomeButtonType 2,DeviceSupportsDynamicIsland true,DeviceSupportsEnhancedMultitasking false,IsLargeFormatPhone true;ScreenDimensionsCapability 的 main-screen-width 1398、main-screen-height 2034、main-screen-pitch 460、main-screen-scale 3;displaysprimary(displayName LCD,screenID 1,width 1398,height 2034,scale 3,hdpi 与 vdpi 460,refreshRate 60,nativeOrientation 0,cornerRadiusUL 8、UR 59、LL 8、LR 59,colorspace P3)与 primary-1(displayName LCD-1,screenID 3,width 2007,height 2853,scale 3,hdpi 与 vdpi 460,refreshRate 60,nativeOrientation 270,四个圆角半径均为 55,colorspace sRGB),另有 external-0(TVOut)、wireless0(carPlay)和 resizable(scene)。两个 framebufferMaskIdentifier 的 PDF 用 qlmanage 渲染后查看。Apple 规格表上关于面板的数字见那篇 Duo 开发者文章。在 beta 下运行 xcrun simctl list devicetypes 会列出“iPhone Duo (com.apple.CoreSimulator.SimDeviceType.iPhone-Duo)”。 

  6. 作者在 macOS 26.6.2(25G83)上于 2026 年 9 月 19 日和 20 日的运行。设备:simctl create "Duo-27.1" com.apple.CoreSimulator.SimDeviceType.iPhone-Duo com.apple.CoreSimulator.SimRuntime.iOS-27-1,用 simctl bootsimctl bootstatus -b 启动(在这台 Mac 上约一分钟);simctl io <udid> enumerate 列出两个显示类别为 0 的 com.apple.framebuffer.display 端口,分别是 1398 × 2034 和 2007 × 2853,并在 Connected Screens 下列出“LCD-1”,设备名 primary-1,屏幕 ID 3,像素尺寸 {2007, 2853}。探针:DuoProbe,一个单文件 SwiftUI 应用,在 Xcode 27.1 beta 下用 xcrun swiftc -sdk <iPhoneSimulator.sdk> -target arm64-apple-ios27.1-simulator -parse-as-library 构建,用 simctl install 安装,用 simctl launch --console-pty 启动,截图用 simctl io <udid> screenshot --mask=alpha --display=primary--display=primary-1。合上姿态的控制台行:DUOPROBE screen=(466.0, 678.0) scale=3.0 idiom=0 model=iPhone name=Duo-27.1DUOPROBE size=386x510 h=compact v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 0.0, bottom: 34.0, trailing: 0.0)DUOPROBE uikit bounds=(354.0, 44.0) divisions=0 occlusions=0 verticalBarEdge=UIVerticalBarEdge(rawValue: 0);没有 division[occlusion[ 开头的行。--display=primary-1 的截图是黑的。屏幕电源:simctl io <udid> screenConfig --display=primary power off 打印“Screen 1 power state set to off”;随后的 simctl launchFBSOpenApplicationServiceErrorDomain 代码 5 失败,提示“The system shell probably crashed.”;simctl shutdownboot 让设备恢复。姿态相关的运行在 9 月 20 日分两轮进行,两轮都通过辅助功能 API 对 Device Hub 为所选设备提供的按钮执行 AXPress 动作,依次按下 Rotate Right、Closed、Book 和 Open,并且两轮都由 27.2 beta 的 simctl 命令行工具(脚本所设置的 DEVELOPER_DIR)驱动,针对的是 27.1 beta 的运行时、设备类型和 Device Hub。第一轮中,按下下一个按钮时上一种姿态的探针仍在运行,之后才终止并重新启动,控制台捕获十二秒,并对两块屏幕分别截图;上文中旋转后的读数和过渡行来自这一轮。第二轮中,每次捕获后都终止探针,因此按下下一个按钮时前台没有应用;重新启动前的截图来自这一轮。Open:DUOPROBE size=803x515 h=regular v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 34.0, bottom: 20.0, trailing: 34.0)DUOPROBE uikit bounds=(771.0, 44.0) divisions=0 occlusions=0 verticalBarEdge=UIVerticalBarEdge(rawValue: 0)DUOPROBE screen=(466.0, 678.0)--display=primary-1 的截图中能看到探针,--display=primary 是黑的。Book:重新启动后是同样的三行;按下按钮之后、重新启动之前拍下的内屏截图显示的是主屏幕,此时没有应用在运行。Closed:即上面那几行合上姿态的输出。Rotate Right 之后再 Open:DUOPROBE size=669x703 h=regular v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 0.0, bottom: 34.0, trailing: 0.0)uikit bounds=(637.0, 44.0),内屏截图为竖向。没有任何一次运行打印过 division[occlusion[ 行。旋转后的合上状态只作为姿态切换过程中的过渡行出现过,即 DUOPROBE size=610x232 h=compact v=compact ... screen=(678.0, 466.0),未计入上文。 

  7. Apple,2026 年 9 月 19 日获取的文档 JSON,涉及 ArrangementViewUIArrangementViewControllerreservedRegions(kind:options:layoutDirectionBehavior:)reservedRegions(kind:options:)toolbarVerticalBehavior(_:):每个页面的平台可用性都写着 iOS 27.1 和 iPadOS 27.1,并标记为 beta。Apple,Preparing your app for iPhone Duo,同日获取,用于确认该指南所使用的名字。 

  8. Apple,Xcode 27.2 Beta Release Notes,2026 年 9 月 19 日获取,SDK、Known Issues、187160501,引用。 

  9. Apple,“Get ready with the latest beta releases”,新闻,2026 年 9 月 16 日,“Note about iOS 27.1 and iPhone Duo”,引用。 

  10. Apple,Designing for iPhone Duo,Human Interface Guidelines,2026 年 9 月 20 日通过文档 JSON 端点获取:“Controls on the side include both system and app elements: the Dynamic Island, the status bar, the toolbar (including navigation buttons), and the tab bar.”以及“A hinge in the center lets people open and close the device”。 

  11. Apple Newsroom,Apple unveils iPhone Duo,2026 年 9 月 9 日,2026 年 9 月 20 日获取:“Set iPhone Duo down and it enters StandBy on either the outer or inner display”和“hub for widgets”,引自 StandBy 段落。 

相关文章

arm64e.x1:Apple 的检查式指针运算切片

iOS 27 RC 发行说明新增 arm64e.x1:在 A20 Pro、M6 和 S11 上启用的检查式指针运算(CPA2)。clang 生成什么指令、Xcode 的四个开关,以及支持的硬件清单。

11 分钟阅读

iOS 27.0发行说明:弃用、破坏性变更与修复

iOS 27.0(24A437)于9月14日发布。从开发者角度解读这份说明:11项弃用、用27 SDK构建时会触发什么,以及我亲自验证的一项修复。

20 分钟阅读

为 iPhone Duo 做设计:什么会移动,什么会分栏,什么保持不动

把 Apple 的 iPhone Duo 设计指南和三场 Tech Talk 当作规则来读:用两个尺寸类别取代逐一适配的姿态、折痕处的位移、arrangement,以及侧边栏。

16 分钟阅读