iOS 27.0发行说明:弃用、破坏性变更与修复
iOS 27.0和iPadOS 27.0于2026年9月14日(周一)以版本号24A437正式发布,与Apple在9月11日发布的RC是同一个版本号;同一天,Xcode 27(27A266a)内置的SDK随之推出,App Store Connect也从当天起接受27.0 GA构建。13 现在,“到底是哪个iOS 27.0”这个问题有三个版本号可以回答:设备运行的是24A437,Xcode 27内的SDK自称24A430,模拟器运行时则是24A434。4 发行说明覆盖93个带标题的领域,包含65项新功能、197项已解决问题、23项已知问题和11项弃用;对既有代码真正重要的,是用27.0 SDK构建的那一刻就会触发的那组变更、在SDK自身头文件中得到证实的弃用,以及一项Foundation修复,用同一个二进制文件就能在iOS 26.5和iOS 27.0两个运行时上复现。24 {.answer-block}
TL;DR
- 版本号。 设备24A437,SDK 24A430,模拟器运行时24A434;RC和GA共用一个设备版本号,而SDK的编号并不是设备的编号,当错误报告要你提供版本号时,这一点很关键。14
- 链接到27后的行为。 12类变更、共23个条目,会在你用27.0 SDK构建的那一刻改变应用的行为:启动屏幕成为必需项、场景生命周期强制要求、
TabView在选中隐藏标签时崩溃、可选择的Text启用系统文本选择、被呈现的视图控制器的特征继承、内联作用域栏、外接显示器场景不再自动提供、sheet和popover内控件修饰符被重置、containerRelativeFrame的安全区域计算、状态栏访问器、UIRequiresFullScreen下的iPad调整大小规则,以及菜单和滚动到顶部方面两个较小的SwiftUI变化。2 - 不重新编译就会崩溃。 MetricKit的
HitchTimeMetric.ratio现在以新的HitchTimeRatio单位度量,ScrollHitchTimeMetric则从Swift API中移除;Apple表示要用最新SDK重新编译,以避免启动时崩溃和符号缺失崩溃,SDK接口也证实该类型已不存在。24 - 11项弃用,大多悄无声息。
canOpenURL:(头文件中为ios(3.0, 27.0))、On Demand Resources(ios(9.0, 27.0))、PHAssetResource.originalFilename(ios(9, 27))、原有的MetricKit API(标记为API_TO_BE_DEPRECATED,属于软弃用)、ScrollHitchTimeMetric、FileDocument、calendar.deleteEvents改名为calendar.deleteEvent、一处PencilKit改名、场景强制要求、AirPort实用工具,以及一条关于Weather Highlights的语言说明。三项硬弃用只在部署目标为27.0时才发出警告;在17.0或26.0下,同一个文件可以干净地编译通过。24 - 两项Foundation变更,已测试。
+[NSURL URLWithString:]在转义字符串中其他位置的空格时,不再对合法的%20做二次编码:同一个模拟器二进制文件在iOS 26.5运行时上输出%2520,在iOS 27.0运行时上输出%20,而Mac构建与旧行为一致,所以这项修复跟随的是操作系统,而不是SDK。volumeAvailableCapacityKey截断为三位有效数字的变更在模拟器中没有出现,模拟器精确报告了55,177,985个块。24
哪个版本号对应哪里?
| 位置 | 版本号 | 证据 |
|---|---|---|
| 设备,iOS 27.0 / iPadOS 27.0 | 24A437 | Releases订阅源,2026年9月14日(周一);9月11日(周五)为“iOS 27.0 RC (24A437)”1 |
| Xcode 27(27A266a)内的SDK | 24A430 | iPhoneOS.sdk/System/Library/CoreServices/SystemVersion.plist中的ProductBuildVersion4 |
| iOS 27.0模拟器运行时 | 24A434 | xcrun simctl list runtimes输出“iOS 27.0 (27.0 - 24A434)”4 |
| macOS 27.0 | 26A428 | Releases订阅源,9月14日(周一)1 |
| App Store Connect | 接受27.0 GA SDK | “You can now upload apps built with Xcode 27 using the SDK for iOS 27.0, iPadOS 27.0, macOS 27.0, tvOS 27.0, visionOS 27.0, and watchOS 27.0 for the App Store, and for internal and external testing through TestFlight.”(现在可以上传用Xcode 27和27.0 SDK构建的应用,用于App Store以及通过TestFlight进行的内部和外部测试)9月14日;RC SDK的上传自9月9日起接受3 |
三个编号并不是错误。SDK是头文件和接口的快照,模拟器运行时是Apple单独交付给Xcode的cryptex,而设备版本号是人们实际运行的东西;一份只写“iOS 27.0”而不带其中任何一个编号的复现步骤,缺少的正是决定修复是否已生效的那个数字。4
发行说明本身以两句范围声明开头:“The iOS & iPadOS 27 SDK provides support to develop apps for iPhone and iPad running iOS & iPadOS 27. The SDK comes bundled with Xcode 27, available from the Mac App Store.”(iOS & iPadOS 27 SDK支持为运行iOS & iPadOS 27的iPhone和iPad开发应用,该SDK随可从Mac App Store获取的Xcode 27一同提供)随后逐一列出93个带标题的领域。数一数每个标题下的列表项,得到65项新功能、197项已解决问题、23项已知问题和11项弃用;仅Siri就占了38项已解决和8项已知,SwiftUI有23项新功能和13项已解决,UIKit有9项新功能和13项已解决。2 Xcode 27那篇文章讲工具链一侧,而你正在读的这篇讲操作系统和SDK一侧。
用27.0 SDK构建的那一刻会改变什么?
Apple以应用链接的SDK作为行为变更的开关,所以这些变更对你已经发布的构建不起任何作用,而在你从Xcode 27做第一次归档时会全部触发。以下逐条引用说明原文:2
- 启动屏幕。 “iOS and iPadOS apps built with the 27.0 SDK or later are required to include a launch screen. Your app’s
Info.plistmust contain one of the following keys:UILaunchStoryboardName,UILaunchStoryboards,UILaunchScreen, orUILaunchScreens. Apps that don’t include a launch screen are rejected when the App Store begins accepting apps built with the 27.0 SDK.”(用27.0或更高版本SDK构建的应用必须包含启动屏幕,Info.plist中须含上述键之一;当App Store开始接受27.0 SDK构建时,不含启动屏幕的应用会被拒绝)App Store Connect从9月9日起接受用27.0 RC SDK构建的App Store上传,从9月14日起接受GA SDK构建;两条记录都没有说拒绝从何时开始,所以请把两者都当作上传日期,而不是强制执行日期。3 我的启动屏幕文章审查了一份自动生成的plist。 - 场景生命周期。 在UIKit弃用项下:“Apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch.”(用最新SDK构建的应用必须采用基于场景的生命周期,否则无法启动)迁移方法见场景强制要求文章。
TabView的选中项。 “In apps built with the iOS 27.0 and iPadOS 27.0 SDKs, aTabViewenforces that its selection is set to a visible tab.TabViewmight crash when its selection is set to a hidden or otherwise unavailable tab.”(在用iOS 27.0和iPadOS 27.0 SDK构建的应用中,TabView强制要求选中项必须是可见标签;若选中项被设为隐藏或不可用的标签,TabView可能崩溃)需要留意的典型情形是:从UserDefaults恢复的选中项指向了你后来隐藏的标签。- 可选择的
Text。 “In apps built with the iOS 27.0 and iPadOS 27.0 SDKs, aTextview with.textSelection(.enabled)applied now supports user-interactive selection using the system text selection UI.”(在用27.0 SDK构建的应用中,应用了.textSelection(.enabled)的Text视图现在支持通过系统文本选择界面进行交互式选择)Apple补充说,这类视图“might include additional gestures for system text selection interactions”(可能包含用于系统文本选择交互的额外手势),并建议自定义手势使用.highPriorityGesture();同一构建还让TextRenderer能作用于可选择的Text。 - 被呈现的视图控制器。 “In apps built with the iOS 27.0 SDK, a presented view controller inherits its trait collection by walking up its view’s superview chain through the intermediate views of the presentation, rather than jumping directly to the presentation controller.”(在用iOS 27.0 SDK构建的应用中,被呈现的视图控制器通过沿其视图的父视图链、经过呈现过程中的中间视图向上查找来继承特征集合,而不是直接跳到呈现控制器)需要重新测试的是那些设置特征的自定义
UIPresentationController子类。 - 作用域栏。 “In apps built with the iOS 27.0 SDK, when
UISearchControlleruses center search-bar placement, the scope bar appears inline on the same row as the search field rather than on a separate row beneath it.”(在用iOS 27.0 SDK构建的应用中,当UISearchController使用居中搜索栏布局时,作用域栏内联显示在与搜索字段同一行,而不是下方单独一行) - 外接显示器。 “In apps built with the iOS 27.0 SDK,
windowExternalDisplayNonInteractivescenes are no longer offered automatically by the system. UseUIViewController.registerSceneAccessory(_:)with aUISceneAccessory.externalNonInteractiveinstance to display non-interactive content on external display scenes.”(在用iOS 27.0 SDK构建的应用中,系统不再自动提供windowExternalDisplayNonInteractive场景;要在外接显示器场景上显示非交互内容,请以UISceneAccessory.externalNonInteractive实例调用UIViewController.registerSceneAccessory(_:))SwiftUI通过.sceneAccessory搭配ExternalNonInteractiveAccessory获得同样的入口。 - Sheet和popover。 列为已修复:“In apps built with the 27.0 SDKs, the
controlSize,buttonSizing,buttonRepeatBehavior,menuIndicatorVisibility, andButtonBorderShapeenvironment values are now reset to their default values in sheets and popovers.”(在用27.0 SDK构建的应用中,这些环境值在sheet和popover内会被重置为默认值)如果某个sheet曾从呈现方继承.controlSize(.large),现在不再继承。 containerRelativeFrame。 同样是针对27.0 SDK构建的修复:它“incorrectly accounts for safe-area insets on aScrollView’s non-scrollable axis, causing the calculated scrollable content size to be too small”(在ScrollView不可滚动的轴上错误地计入了安全区域内边距,导致计算出的可滚动内容尺寸过小),因此使用containerRelativeFrame(.vertical)的水平ScrollView尺寸会发生变化。- 状态栏访问器。 针对27.0 SDK构建的修复:
UIApplication上已弃用的状态栏访问器,说明列出的是statusBarFrame、statusBarOrientation、statusBarStyle和isStatusBarHidden,“might return NaN or null values”(可能返回NaN或null值)。 - iPad和iPhone镜像的调整大小与方向。 UIKit的9项已解决问题描述了“built with the iOS 27 SDK”(用iOS 27 SDK构建)的应用在场景连接时,或用户调整窗口大小、旋转窗口时应看到的行为:
UIRequiresFullScreen应用得到的是“a discrete change to a newUIScreenwith an updated bounds”(一次切换到具有更新后bounds的新UIScreen的离散变化)而不是连续的尺寸更新,UIScreen.main的bounds“should remain fixed once the screen connects”(在屏幕连接后应保持固定),并且“supported interface orientations should no longer be a condition for continuous resizability”(支持的界面方向不应再作为连续调整大小的条件)。 - 菜单和滚动到顶部。 两个较小的SwiftUI变化:“In apps built with the 27.0 SDKs, a
LabeledContentview used inside aMenumaps its value to the platform menu item’s subtitle”(在用27.0 SDK构建的应用中,Menu内使用的LabeledContent视图会把其值映射为平台菜单项的副标题),以及列为已修复的“In apps built with the 2027 SDKs, tapping the status bar to scroll aScrollViewto its top correctly updates a boundscrollPosition”(在用2027 SDK构建的应用中,点按状态栏将ScrollView滚动到顶部时,会正确更新绑定的scrollPosition)。出于布局原因携带了值的菜单标签现在会多出一个副标题,而点按状态栏后读到过期值的scrollPosition绑定现在会更新。
这12类涵盖了所有改变既有行为的条目。同一SDK门槛之后的新能力,比如ReadableDocument协议、建立在它之上的Document协议,以及UIScene.extendStateRestoration,放在后面的章节;外接显示器这一类把UIKit侧的移除和SwiftUI侧的替代配成了一对。
MetricKit的两个条目虽然讲的是重新编译而不是链接,也属于这里。“HitchTimeMetric.ratio and SignpostIntervalMetric.hitchTimeRatio now use the new HitchTimeRatio type, a Dimension subclass that expresses hitch time as a ratio of milliseconds hitching per second of tracked duration. Recompile your app with the latest SDK to pick up this type change and avoid any crashes on launch.”(HitchTimeMetric.ratio和SignpostIntervalMetric.hitchTimeRatio现在使用新的HitchTimeRatio类型,这是一个Dimension子类,以每秒跟踪时长中卡顿毫秒数的比率表示卡顿时间;请用最新SDK重新编译应用以采用此类型变更,避免启动时崩溃)以及:“The scrollHitchTime(_:) case of MetricResult and the ScrollHitchTimeMetric type are no longer part of the new Swift MetricKit API, and MetricReport values no longer contain scroll hitch entries. Use the hitchTime(_:) case and HitchTimeMetric instead, which report per-app animation hitch time. Recompile your app with the latest SDK to avoid a missing symbol crash if it references ScrollHitchTimeMetric or scrollHitchTime(_:).”(MetricResult的scrollHitchTime(_:)分支和ScrollHitchTimeMetric类型不再属于新的Swift MetricKit API,MetricReport值也不再包含滚动卡顿条目;请改用报告每个应用动画卡顿时间的hitchTime(_:)分支和HitchTimeMetric,如果代码引用了这两个名称,请用最新SDK重新编译以避免符号缺失崩溃)2 在iOS 27 SDK的MetricKit Swift接口中,ScrollHitchTimeMetric和scrollHitchTime出现零次,HitchTimeRatio出现四次,所以针对beta SDK构建、用到其中任一名称的二进制文件,引用的是GA接口并不导出的符号。4 我的MetricKit文章介绍了6月beta中的新API。
27.0中弃用了哪些API?
发行说明列出了11项弃用。说明里的一项弃用只是一句话,而SDK里的一项弃用是编译器会读取的可用性注解,两者并不总是说同一件事。我把每一条都对照Xcode 27内iPhoneOS 27.0 SDK中的头文件和Swift接口逐一核对:24
| 说明条目 | SDK怎么说 |
|---|---|
“canOpenURL: is deprecated. Attempt to open the URL and handle any failure instead of validating it first.”(canOpenURL:已弃用;不要先做校验,而是直接尝试打开URL并处理失败) |
UIApplication.h中为API_DEPRECATED("Prefer attempting to open URLs and handling any failures", ios(3.0, 27.0), visionos(1.0, 27.0), tvos(9.0, 27.0));替代模式见canOpenURL文章 |
“On Demand Resources and the NSBundleResourceRequest API are deprecated. Use Background Assets instead.”(On Demand Resources和NSBundleResourceRequest API已弃用,请改用Background Assets) |
类本身、其保留优先级方法以及通知和优先级常量上都有API_DEPRECATED("Use Background Assets instead.", ios(9.0, 27.0), watchos(2.0, 27.0), tvos(9.0, 27.0));ODR文章估算了迁移成本,其FAQ中“你得到的是一条编译器警告”一节现在附上了下一节所述的部署目标限定条件 |
“The originalFilename property on PHAssetResource is incorrectly marked as non-nullable, which misrepresents the property value; a new, nullable filename property is available as a replacement.”(PHAssetResource的originalFilename属性被错误地标记为非可空,未能如实反映属性值;新增了可空的filename属性作为替代) |
originalFilename为API_DEPRECATED("Use filename instead", ios(9, 27), macos(10.15, 27), tvos(10, 27), visionos(1, 27));filename为nullable且API_AVAILABLE(macos(27), ios(27), tvos(27), visionos(27)) |
原有的MetricKit API,即MXMetricManager、MXMetricManagerSubscriber、MXMetricPayload和MXDiagnosticPayload,“are no longer recommended for new adoption. Use MetricManager instead.”(不再推荐新项目采用,请改用MetricManager) |
MXMetricManager上为API_DEPRECATED("Use MetricManager instead.", ios(13.0, API_TO_BE_DEPRECATED), macos(12.0, API_TO_BE_DEPRECATED)):没有版本号的软弃用,所以目前不会有警告。Apple该类的参考页面却把它列为在所有平台上于27.0弃用,文档和头文件互相矛盾;我的MetricKit文章照搬了页面上的版本号,现在已附上一条标注日期的说明来记录这一分歧6 |
ScrollHitchTimeMetric和scrollHitchTime(_:)“are no longer part of the new Swift MetricKit API”(不再属于新的Swift MetricKit API) |
MetricKit.swiftmodule中两个名称均出现零次;不是弃用,而是移除 |
“The FileDocument protocol is deprecated. Use ReadableDocument for read-only documents or Document for documents that support reading and writing.”(FileDocument协议已弃用;只读文档请用ReadableDocument,支持读写的文档请用Document) |
FileDocument:deprecated: 100000.0, message: "Conform your type to Document instead.";ReferenceFileDocument:"Use Document protocol instead.";两者都是软弃用,而Document为@available(iOS 27.0, macOS 27.0, visionOS 27.0, *),所以替代方案需要27的最低版本 |
“The calendar.deleteEvents schema has been renamed to calendar.deleteEvent.”(calendar.deleteEvents schema已改名为calendar.deleteEvent) |
AppIntents.swiftmodule中deleteEvents出现零次;deleteEvent: some AppSchemaIntent存在。没有别名的改名,对仍用旧名称的人来说就是编译错误 |
“__PKStrokeRenderState has been renamed to PKStrokeRenderStateReference, with PKStrokeRenderStateReference.init(…) replacing PKStrokeRenderState.asObjCRenderState().”(__PKStrokeRenderState已改名为PKStrokeRenderStateReference,PKStrokeRenderStateReference.init(…)取代了PKStrokeRenderState.asObjCRenderState()) |
PKStrokeRenderState.h在API_AVAILABLE(ios(27.0), macos(27.0), visionos(27.0))下声明了带NS_SWIFT_NAME(PKStrokeRenderStateReference)的@interface PKStrokeRenderState;Swift接口中完全没有asObjCRenderState;Apple指定的替代是引用类的init(_ swiftValue: PKStroke.RenderState),所以新的调用形式是PKStrokeRenderStateReference(state),旧调用无法编译 |
| “Apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch.”(用最新SDK构建的应用必须采用基于场景的生命周期,否则无法启动) | 不是注解,而是启动失败。见场景强制要求文章 |
| “AirPort Utility will no longer be available for new downloads from the App Store.”(AirPort实用工具将不再可从App Store新下载)重新下载仍然可用;在iOS 27上“functionality is not guaranteed”(不保证功能正常) | 是一个应用,不是API |
| “Weather Highlights is currently only available in US English.”(Weather Highlights目前仅提供美式英语) | Apple把它归入弃用项,但读起来是一条可用性说明 |
在弃用标题之外,还有一项软弃用和一项改名。.roundedBorder文本字段样式在SwiftUI接口中带有deprecated: 100000.0注解,去掉内层反引号后,其消息为“Use textFieldStyle(.bordered) with textInputBorderShape(.roundedRectangle)”(请将textFieldStyle(.bordered)与textInputBorderShape(.roundedRectangle)搭配使用);它与引入TextInputBorderShape的新功能条目相对应。100000.0这个版本号是Apple表示“已弃用,但尚未生效”的惯例:在默认编译器设置下编译器保持沉默,消息只出现在接口里。改名则更棘手。UINavigationItem.navigationBarMinimization“replaces UINavigationItem.barMinimizeBehavior and UINavigationItem.barMinimizationSafeAreaAdjustment”(取代了UINavigationItem.barMinimizeBehavior和UINavigationItem.barMinimizationSafeAreaAdjustment),SwiftUI的toolbarMinimizationBehavior也以同样方式取代了toolbarMinimizeBehavior;这三个旧名称在27.0 SDK的UIKit头文件、UIKit和SwiftUI的Swift接口中都不存在,所以依赖它们的代码会编译失败而不是收到警告,与deleteEvents属于同一类。24
硬弃用也比看上去安静。编译器把弃用版本与你的部署目标比较,而不是与SDK比较,所以ios(3.0, 27.0)只在最低iOS为27.0的目标中才产生警告。我把一个调用canOpenURL、创建NSBundleResourceRequest并读取originalFilename的文件针对27 SDK编译了三次:在-target arm64-apple-ios17.0-simulator和26.0下没有任何诊断信息,在27.0下产生了三条警告:'canOpenURL' was deprecated in iOS 27.0: Prefer attempting to open URLs and handling any failures、'NSBundleResourceRequest' was deprecated in iOS 27.0: Use Background Assets instead.以及'originalFilename' was deprecated in iOS 27: Use filename instead。4 最低版本设置得比较现实的应用,不会从编译器那里听到其中任何一条;在默认编译器设置下,下方清单中的grep是你能得到的唯一提醒。
我验证了哪些修复?
Foundation的两个条目可以直接运行验证,而不只是阅读。说明把第一个列为已修复:“+[NSURL URLWithString:] no longer double-encodes the % of valid percent-escape sequences when encoding other invalid characters.”(+[NSURL URLWithString:]在编码其他非法字符时,不再对合法百分号转义序列中的%做二次编码)2 探测程序用三个字符串构造NSURL(string:),每个字符串都包含一个合法转义和一个NSURL必须转义的字符,然后打印absoluteString。我用Xcode 27构建了两次:一次面向Mac,一次面向最低iOS为26.0的模拟器,然后把那一个模拟器二进制文件原封不动地分别在iOS 26.5运行时和iOS 27.0运行时上运行:4
| 输入 | macOS 26.6.2,以及模拟器二进制在iOS 26.5上(完全相同) | 同一模拟器二进制在iOS 27.0(24A434)上 |
|---|---|---|
https://example.com/a%20b c |
https://example.com/a%2520b%20c |
https://example.com/a%20b%20c |
https://example.com/search?q=caf%C3%A9 au lait |
https://example.com/search?q=caf%25C3%25A9%20au%20lait |
https://example.com/search?q=caf%C3%A9%20au%20lait |
https://example.com/p%20q{r |
https://example.com/p%2520q%7Br |
https://example.com/p%20q%7Br |
第一列是旧行为:NSURL转义了空格,同时把本来就合法的转义中的%也变成了%25,于是得到的路径与转义原本指向的路径不再相同。iOS 27.0那一列是修复后的结果。LC_BUILD_VERSION显示minos 26.0和sdk 27.0的同一个Mach-O产生了两个模拟器列的结果,所以决定结果的是代码运行所在的操作系统,而不是你编译时用的SDK,也不是你构建的目标。你今天构建的应用,在我测试的iOS 26.5运行时上仍保持旧的编码方式,发行说明也没有给出任何理由让人预期其他26.x版本会有不同结果。
说明把第二个列为新功能,而在我能运行代码的地方无法复现它:“volumeAvailableCapacityKey is truncated to 3 significant decimal digits at the block count level (e.g., 123,456,789 blocks becomes 123,000,000 blocks).”(volumeAvailableCapacityKey在块计数层面被截断为三位有效数字,例如123,456,789个块变成123,000,000个块)2 在iOS 27.0模拟器中,URL.resourceValues(forKeys: [.volumeAvailableCapacityKey])返回226,009,026,560字节,对同一路径调用statfs返回f_bavail 55,177,985、f_bsize 4,096,两者相乘恰好等于同一个数字;若是三位有效数字的块计数,应当是55,100,000个块,即225,689,600,000字节。4 宿主Mac用同样的代码报告了55,177,998个块。我的理解是,这个截断位于设备内核而不是Foundation,而模拟器向Mac内核查询的是Mac的卷,因此无从显示;我没有在真机上运行这个探测程序,所以请把这一条当作未经测试而不是不成立,并预期设备上过去精确的可用空间报告会出现舍入。
哪些新功能会影响你已有的代码?
HealthKit的有限历史。 说明只有一行:“Updated HealthKit permissions flow now lets users grant apps access to limited history or full history”(更新后的HealthKit权限流程允许用户授予应用访问有限历史或完整历史的权限),后果则写在API参考里。25 在数据类型界面之后,“a second screen prompts them to choose how much historical data to grant your app, either a recent limited window or their full history”(第二个界面会提示用户选择授予应用多少历史数据,是近期的有限窗口还是完整历史),并且“Time-bound authorization applies only to sample types”(有时限的授权仅适用于样本类型)。5 自iOS 27.0和watchOS 27.0起可用的新方法earliestAuthorizedSampleDate(for:)返回一个从HKObjectType到最早可读日期的字典,而边界并不在你猜的位置:“HealthKit evaluates the boundary against a sample’s end date, so the framework might service your query with a sample that begins before the earliest authorization date as long as the sample ends after it.”(HealthKit以样本的结束日期来评估边界,因此只要样本在最早授权日期之后结束,即使它在该日期之前开始,框架也可能把它返回给你的查询)45 隐私规则依然成立:“Your app can’t distinguish between denied and full access; limited authorization is the only state your app can identify, by design.”(应用无法区分被拒绝和完整访问;有限授权是应用唯一能识别的状态,这是有意为之的设计)5 Apple的建议是把返回日期之前的一切视为未知而不是不存在,并按类型逐个限定每次查询的起始日期。现在,任何根据HealthKit计算的趋势、基线或连续记录,都必须在用户选定的窗口上保持正确。HealthKit文章介绍了6月的新增内容,没有涉及这次权限模型的变更。
StoreKit优惠代码。 “Offer code redemption APIs now return a VerificationResult when redemption completes. If a redemption succeeds, your app receives a VerificationResult that contains a Transaction object. If a redemption fails, your app receives an error that describes what caused the redemption to fail.”(优惠代码兑换API现在在兑换完成时返回VerificationResult;兑换成功时应用收到包含Transaction对象的VerificationResult,失败时收到描述失败原因的错误)2 在接口中,presentOfferCodeRedeemSheet(in:)于27.0弃用,消息为“Use presentOfferCodeRedeemSheet(from:options:) instead.”(请改用presentOfferCodeRedeemSheet(from:options:)),替代方法是自iOS 27.0起可用的presentOfferCodeRedeemSheet(from viewController: UIViewController, options: Set<RedeemOption> = []) async throws -> VerificationResult<Transaction>。4 以前先呈现sheet、再在Transaction.updates上监听结果的代码,现在可以直接await。
后台的Core AI。 “The system now restricts background access to the Neural Engine, similar to GPU usage restrictions”(系统现在限制后台访问Neural Engine,类似于GPU使用限制),以及“Neural Engine memory usage is now attributed to your app process instead of the system, and appears in the Allocations instrument”(Neural Engine内存使用现在计入应用进程而不是系统,并显示在Allocations工具中)。后台访问“requires the new entitlement: “com.apple.developer.background-tasks.continued-processing.inference””(需要新的授权)。2 在26上从后台任务运行推理、从未申请过任何东西的应用,会发现Neural Engine已经关闭,直到它持有这项授权;它使用的Neural Engine内存现在会在Allocations中显示在自己的进程之下。
Background Assets。 “You can reduce your app’s storage usage with localized asset packs. The system delivers the appropriately localized asset packs based on the user’s preferred languages.”(你可以用本地化资源包减少应用的存储占用,系统会根据用户的首选语言交付相应的本地化资源包)2 对于正在离开On Demand Resources的应用,本地化资源包正是取代按语言打标签的那项功能。
紧急警报。 说明把紧急警报的行为列为已修复:“Critical alerts are automatically turned on for any apps that request your permission to enable notifications.”(对于任何请求通知权限的应用,紧急警报会自动开启)2 这一条没有更多内容,所以请重新测试所有在beta期间看起来权限过高的通知流程。
菜单、@State、TLS和新切片。 四个条目各有专文。iPadOS 27和macOS 27上的菜单栏和上下文菜单“present a reduced set of menu item images”(只显示精简后的菜单项图片),可通过UIMenuElement上的preferredImageVisibility覆盖:见菜单图片。@State宏的重写是这份说明中的一个SwiftUI条目,它改变了Xcode 27下哪些代码能编译:复现见Xcode 27文章,审查见@State宏文章。对MDM、注册和软件更新流量更严格的TLS要求“in 27.0 operating systems”(在27.0操作系统中)开始生效:见TLS审查。带CPA2的arm64e.x1适用于“iPhone models with A20 Pro or later chips, Mac computers with M6 or later chips, and Apple Watch models with S11 or later chips”(搭载A20 Pro或更新芯片的iPhone、搭载M6或更新芯片的Mac,以及搭载S11或更新芯片的Apple Watch):见arm64e.x1。2
值得grep一下的小变更。 System新增了Swift版的stat、lstat、fstat和fstatat,附带Stat类型和FilePath.stat(),说明还把这些方法与你自己扩展中未限定的stat()之间的冲突列为已修复。NSTextTable“and its related objects and types are available to UIKit clients starting with OS 27 releases”(及其相关对象和类型自OS 27版本起可供UIKit客户端使用)。AsyncImage“now automatically caches downloaded images using HTTP caching protocols”(现在会按HTTP缓存协议自动缓存下载的图片),并提供URLRequest初始化器和View.asyncImageURLSession(_:)来控制它。“When linked on iOS 27, tvOS 27, macCatalyst 27, or visionOS 27 SDKs”(当链接到iOS 27、tvOS 27、macCatalyst 27或visionOS 27 SDK时),UIScene.extendStateRestoration和UIScene.completeStateRestoration把状态恢复延伸到从后台到前台的过渡中。SwiftData则列出了对“a deadlock for @Query when saving a ModelContext on a background actor while scheduling new async tasks for a ModelActor”(在后台actor上保存ModelContext、同时为ModelActor调度新的异步任务时@Query出现死锁)的修复。2
需要提前规划的已知问题
photos.asset实体无法编译。 “Existing entities that conformed to @AppEntity(schema: .photos.asset) in prior releases might no longer compile in the 27 SDKs because new properties were added to the schema in this release.”(在之前版本中遵循@AppEntity(schema: .photos.asset)的既有实体,在27 SDK中可能无法再编译,因为本版本向该schema添加了新属性)解决方法:“To continue conforming to the schema, adopt the additional properties and move the code behind an availability check.”(要继续遵循该schema,请采用新增属性并把代码放到可用性检查之后)2 宏不会告诉你是哪些属性:一个空的@AppEntity(schema: .photos.asset)遵循声明在swiftc下可以干净地编译,其展开只添加了一个携带schema名称的AssistantSchemaEntity遵循。这份清单来自Xcode的App Intents元数据步骤appintentsmetadataprocessor,它会为每个缺失属性报一个错误并使构建失败。对那个空遵循声明手动针对27.0 SDK运行,它报告了12项,每项都附有fix-it:hasSuggestedEdits: Bool、isFavorite: Bool、isHidden: Bool、creationDate: Date?、location: GeoToolbox.PlaceDescriptor?、assetType: <#PhotoAssetType#>?、filter: <#PhotoFilterEffectType#>?、exposure: Double?、saturation: Double?、warmth: Double?、aperture: Double?和isPortraitModeEnabled: Bool?;两个<#…#>占位符代表你需要针对.photos.assetType和.photos.filterType枚举schema自行声明的枚举,接口把它们命名为PhotoAssetType和PhotoFilterEffectType。我无法把这份清单与26 SDK做差异比较,因为这台Mac上唯一的Xcode是27A266a。4- Now Playing令牌指向production。 “
RemoteMediaSessionandRemoteMediaSessionRepresentablealways provision Now Playing start and update push tokens for theproductionAPNs environment, even if theaps-environmentconfiguration is set todevelopment.”(即使aps-environment配置为development,RemoteMediaSession和RemoteMediaSessionRepresentable也总是为productionAPNs环境签发Now Playing的启动和更新推送令牌)解决方法:“Use theproductionenvironment for testing and validation.”(测试和验证请使用production环境)2 该类位于新的NowPlaying框架中,在macOS和visionOS上标记为不可用。4 SpotlightSearchTool撑爆设备端模型。 在没有配置的情况下,“the tool’s description and parameter schema alone exceed the on-device model’s context window before any prompt is added”(仅工具描述和参数schema本身,就在添加任何提示词之前超出了设备端模型的上下文窗口)。解决方法是一个聚焦的指南:“.focused(.communications),.focused(.calendar),.focused(.documents),.focused(.visualMedia), or.focused(.audio)”。2 这个API是真实存在的:SpotlightSearchTool.Guide.focused(_ domain: ContentDomain = .items)在_CoreSpotlight_FoundationModels接口中与.complete和.dynamic(_:)并列。4 我的设备端AI文章介绍了这个工具;其6月的采用步骤把默认配置与系统模型配在了一起,现在附上了一条标注日期的更正。- 来自控制中心的性能追踪。 “Gathering
PowerProfilerandLookbacktraces through thePerformance TraceControl Center widget might fail to produce traces.”(通过Performance Trace控制中心小组件采集PowerProfiler和Lookback追踪可能无法生成追踪文件)Apple给出的解决方法是“Gather traces on iOS 27.0 beta 1 or earlier”(在iOS 27.0 beta 1或更早版本上采集追踪),对于已经升级的设备,大多数团队都无法采用这个办法。2 - StoreKit测试。 “Changing the storefront or locale using
SKTestSessiondoesn’t propagate throughStorefront.updates”(用SKTestSession更改店面或区域设置不会通过Storefront.updates传播),以及“Failed purchases usingSKTestSessionmight display error dialogs even whendialogsDisabledis set to true”(使用SKTestSession的失败购买即使在dialogsDisabled设为true时也可能显示错误对话框)。2 - 快捷指令与
UnionValue。 带有“two number-related types (for example, both Int and Double)”(两种数字相关类型,例如同时有Int和Double)的参数会把数字选项显示两次;Apple的解决方法是只声明一种。2
这周我会做什么
- 用Xcode 27归档一次,在上传TestFlight之前对照上面的“链接到27”清单检查应用:启动屏幕键、场景生命周期、任何选中项可能指向隐藏标签的
TabView,以及任何继承了控件修饰符的sheet。2 - 发布前用GA SDK构建MetricKit代码;按Apple的描述,仍引用
ScrollHitchTimeMetric或旧ratio类型的二进制文件会在启动时崩溃,而接口已不再导出该名称。24 - grep一下
canOpenURL、NSBundleResourceRequest、originalFilename、FileDocument、deleteEvents、asObjCRenderState和barMinimizeBehavior;前三个只在部署目标为27.0时警告,FileDocument是软弃用,后三个会编译失败,所以grep就是你的提醒。4 - 如果你读取HealthKit,请在授权后调用
earliestAuthorizedSampleDate(for:),并按类型限定每次查询的起始日期;然后决定在用户选定的窗口上,连续记录或基线应当意味着什么。5 - 在错误报告中从三个地方记录版本号:设备上的
ProcessInfo、构建机器上SDK的SystemVersion.plist,以及用于模拟器复现的simctl list runtimes。它们各不相同,24A437中的修复未必在24A434中。4 - 如果你用
NSURL(string:)从字符串构造URL,请继续在iOS 26上测试:修复%25二次编码的是操作系统而不是你的重新构建,同一个Xcode 27二进制文件在26.5运行时上会产生它,在27.0上则不会。4
常见问题
iOS 27.0是什么时候发布的,版本号是多少?
2026年9月14日(周一),版本号24A437,与Apple在9月11日(周五)发布的候选版本是同一个版本号。iPadOS 27.0共用这个编号。1
Xcode 27 SDK里的iOS 27.0是哪个版本号?
Xcode 27(27A266a)内的iPhoneOS 27.0 SDK报告的ProductBuildVersion为24A430,iOS 27.0模拟器运行时报告为24A434。两者都不是设备版本号。4
iOS 27弃用了什么?
说明列出11项:canOpenURL:、On Demand Resources和NSBundleResourceRequest、PHAssetResource.originalFilename、原有的MetricKit API、ScrollHitchTimeMetric、FileDocument、calendar.deleteEvents schema、__PKStrokeRenderState、UIKit场景生命周期强制要求、AirPort实用工具,以及一条Weather Highlights语言说明。其中三项在SDK中带有硬性的27.0弃用版本,只在部署目标为27.0时警告;两项是软弃用,两项是改名,一项是移除,三项不是API变更。24
我的应用需要为iOS 27重新构建吗?
要保持运行的话不需要,这些条目分为三类。受SDK门槛控制的:上面“链接到27”的12类,在你用27.0 SDK构建之前什么都不会改变。操作系统层面、影响27.0设备上每个二进制文件的:Neural Engine后台限制及其授权、HealthKit的有限历史权限流程、针对MDM和更新流量的TLS强制要求、iPadOS 27上的菜单图片变化、紧急警报修复,以及NSURL编码修复。beta二进制相关的:针对beta SDK构建的MetricKit代码,Apple要求用GA SDK重新编译以避免崩溃。自2026年4月28日起,Apple的App Store SDK最低要求一直是26 SDK;27 SDK的要求是之后的截止日期,这份说明并未设定。23
iOS 27发行说明在哪里?
在Apple开发者文档网站的iOS & iPadOS Release Notes下,27.0有单独一页,按领域组织,每个领域下分为New Features、Resolved Issues、Known Issues和Deprecations。本文的统计数字来自2026年9月15日获取的该页面。2
NSURL的修复在SDK里还是在操作系统里?
在操作系统里。用Xcode 27针对27.0 SDK、以最低iOS 26.0构建的同一个模拟器二进制文件,在iOS 26.5运行时上会二次编码,在iOS 27.0运行时上不会,而macOS 26.6.2上的Mac构建也会二次编码;两次模拟器运行之间,唯一变化的就是操作系统。4
来源
-
Apple,Releases,2026年9月15日获取的RSS订阅源:2026年9月14日(周一)日期下有“iOS 27.0 (24A437)”“iPadOS 27.0 (24A437)”“macOS 27.0 (26A428)”“Xcode 27 (27A266a)”“tvOS 27.0 (24J361)”“visionOS 27.0 (24M362)”和“watchOS 27.0 (24R364)”;2026年9月11日(周五)日期下有“iOS 27.0 RC (24A437)”;2026年6月8日(周一)日期下有“iOS 27.0 beta (24A5355q)”。 ↩↩↩↩↩
-
Apple,iOS & iPadOS 27 Release Notes,GA发布后于2026年9月15日获取。统计数字(93个带标题的领域;65项New Features、197项Resolved Issues、23项Known Issues、11项Deprecations)为各领域标题下的列表项计数。引用的条目按radar编号列出:Overview段落;UIKit,New Features(启动屏幕168247372、被呈现的视图控制器170005251、作用域栏173860616、外接显示器177015874、状态恢复161843040、菜单图片与
preferredImageVisibility170479084、navigationBarMinimization177953926),Resolved Issues(状态栏访问器162044221、调整大小166422120、178555304、178558224、178558897、178559386、178560235、178561952、178562971、178573319),Deprecations(场景生命周期141837548、canOpenURL:179874781);SwiftUI,New Features(TabView164516837、可选择的Text79770704、可选择Text上的TextRenderer158160386、.sceneAccessory175548901、AsyncImage78212597、@State105893279、菜单图片170480710、TextInputBorderShape173362083、toolbarMinimizationBehavior177954148),Resolved Issues(sheet和popover 167448274、containerRelativeFrame165913417、点按状态栏后的scrollPosition111501113、FB12477370),New Features(Menu内的LabeledContent175594929),Deprecations(FileDocument178776840);MetricKit,New Features(HitchTimeRatio180024784)和Deprecations(174892111、180455992);Foundation,New Features(volumeAvailableCapacityKey75545872)和Resolved Issues(NSURL161588649、FB20439045);App Intents,Known Issues(photos.asset181800016、FB23652582)和Deprecations(calendar.deleteEvent176751155);On Demand Resources,Deprecations(170066290);PhotoKit,Deprecations(175412725、FB22589474);PencilKit,Deprecations(176410709);AirPort Utility,Deprecations(158364073);Weather Highlights,Deprecations(164408676);HealthKit,New Features(172310874);StoreKit,New Features(141012819);Core AI,New Features(174796039、179282606);Background Assets,New Features(163944365);Notifications,Resolved Issues(179179362);Network Security,New Features(176055825);Hardware Security,New Features(152103975);System,New Features(160612181)和Resolved Issues(177911316);TextKit,New Features(159870239);SwiftData,Resolved Issues(178113288);Now Playing,Known Issues(186036238);Core Spotlight,Known Issues(183770678);Control Center,Known Issues(184729556);StoreKit Testing in Xcode,Known Issues(184155259、184255116);Shortcuts,Known Issues(168315587)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple,App Store Connect release notes,2026年9月15日获取。2026年9月14日的条目已在表中完整引用;2026年9月9日的条目记录了RC SDK上传的接受情况。自2026年4月28日起的26 SDK最低要求来自Apple的Upcoming requirements页面。 ↩↩↩↩
-
作者复现:
DEVELOPER_DIR指向Xcode 27.0(27A266a),macOS 26.6.2(25G83),2026年9月15日。版本号:iPhoneOS.sdk/System/Library/CoreServices/SystemVersion.plist中ProductBuildVersion为24A430、ProductVersion为27.0;xcrun simctl list runtimes输出“iOS 27.0 (27.0 - 24A434)”。头文件和接口均位于iPhoneOS.sdk/System/Library/Frameworks下:UIKit.framework/Headers/UIApplication.h第98行(canOpenURL:);Foundation.framework/Headers/NSBundle.h第721至796行(NSBundleResourceRequest);Photos.framework/Headers/PHAssetResource.h第29行和第33行;MetricKit.framework/Headers/MXMetricManager.h第32行;MetricKit.framework/Modules/MetricKit.swiftmodule/arm64e-apple-ios.swiftinterface中ScrollHitchTimeMetric或scrollHitchTime零次匹配、HitchTimeRatio四次匹配;SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64e-apple-ios.swiftinterface第23088至23093行(FileDocument)、第9334至9338行(ReferenceFileDocument)、第1728至1731行(Document)、第9489行(.roundedBorder消息)、第13763行(toolbarMinimizationBehavior);在UIKit.framework/Headers、UIKit.framework/Modules和SwiftUI.framework/Modules中,barMinimizeBehavior、barMinimizationSafeAreaAdjustment或toolbarMinimizeBehavior的完整标识符匹配为零(唯一的子串命中是toolbarMinimizationSafeAreaAdjustment修饰符及其ToolbarMinimizationSafeAreaAdjustment类型),而UINavigationItem.h声明了navigationBarMinimization;AppIntents.framework/Modules/AppIntents.swiftmodule/arm64e-apple-ios.swiftinterface中deleteEvents零次匹配,deleteEvent: some AppIntents::AppSchemaIntent位于第12608行;PencilKit.framework/Headers/PKStrokeRenderState.h第15至17行,以及PencilKit.framework/Modules/PencilKit.swiftmodule/arm64e-apple-ios.swiftinterface中asObjC零次匹配、PKStrokeRenderStateReference上的convenience public init(_ swiftValue: PencilKit::PKStroke.PencilKit::RenderState)位于第46行、PKStroke.RenderState内反向的public init(_ objcValue: PencilKit::PKStrokeRenderStateReference)位于第38行;StoreKit.framework/Modules/StoreKit.swiftmodule/arm64e-apple-ios.swiftinterface第311至322行;HealthKit.framework/Modules/HealthKit.swiftmodule/arm64e-apple-ios.swiftinterface第741行和第742行(earliestAuthorizedSampleDate(for:),@available(iOS 27.0, watchOS 27.0, macCatalyst 27.0, macOS 27.0, visionOS 27.0, *));NowPlaying.framework/Modules/NowPlaying.swiftmodule/arm64e-apple-ios.swiftinterface第180至182行和第276至278行;_CoreSpotlight_FoundationModels.framework/Modules/_CoreSpotlight_FoundationModels.swiftmodule/arm64e-apple-ios.swiftinterface第64至78行和第100至129行。photos.asset探测:一个15行的Swift文件,导入AppIntents和CoreLocation,声明@AppEntity(schema: .photos.asset) struct ProbeAsset,带有EntityQuery、id和displayRepresentation,不含任何schema属性;swiftc -c -target arm64-apple-ios27.0-simulator以退出码0、无诊断信息编译通过,-Xfrontend -dump-macro-expansions显示宏在@available(iOS 27.0, macOS 27.0, tvOS 27.0, watchOS 27.0, visionOS 27.0, *)属性下添加了extension ProbeAsset: AssistantSchemaEntity { static let __appSchemaEntity = "photos.asset" }和一个空的AppEntity扩展。重新运行驱动程序自身的swift-frontend命令行(用swiftc -###捕获),加上-emit-const-values-path以及指向我编写的18个协议清单(AppIntent、AppEntity、AppEnum、AssistantSchemaEntity、EntityQuery和其他App Intents协议)的-const-gather-protocols-file,生成了一个.swiftconstvalues文件;对它运行appintentsmetadataprocessor --module-name ProbeMod --sdk-root <iPhoneSimulator27.0.sdk> --xcode-version 27A266a --platform-family iOS --deployment-target 27.0 --target-triple arm64-apple-ios27.0-simulator,以退出码255结束,输出“At least one halting error was produced during export”,以及12行形如“error: Missing required property ‘exposure’ from AppSchemaEntity ‘photos.asset’”的错误,每行后跟一条fix-it,例如“var exposure: Double?”(assetType和filter的fix-it带有<#PhotoAssetType#>?和<#PhotoFilterEffectType#>?占位符;AppIntents.framework/Modules/AppIntents.swiftmodule/arm64e-apple-ios.swiftinterface在第11695行和第11705行分别在assetType下以AppSchema.Enum("PhotoAssetType")、在filterType下以AppSchema.Enum("PhotoFilterEffectType")声明了这些名称);这一调用模仿了Xcode的元数据步骤,但与构建系统的调用并非逐字节相同,构建系统的协议清单来自SWIFT_EMIT_CONST_VALUE_PROTOCOLS。弃用警告探测:一个11行的Swift文件,导入UIKit、Foundation和Photos,调用canOpenURL(_:)、构造NSBundleResourceRequest(tags:)并读取PHAssetResource.originalFilename,针对iPhoneSimulator 27.0 SDK用swiftc -c分别以-target arm64-apple-ios17.0-simulator、ios26.0和ios27.0编译:17.0和26.0下零诊断信息,27.0下三条[#DeprecatedDeclaration]警告,已在正文引用。NSURL探测:一个16行的Swift文件,为表中三个输入打印NSURL(string:)?.absoluteString,面向宿主用swiftc -O编译,并针对iPhoneSimulator 27.0 SDK用swiftc -O -target arm64-apple-ios26.0-simulator编译一次(对结果运行otool -l显示LC_BUILD_VERSION带有minos 26.0和sdk 27.0);我用xcrun simctl spawn把这一个模拟器二进制文件先在已启动的iOS 26.5(23F77)运行时模拟器上运行,再在已启动的iOS 27.0(24A434)运行时iPhone 18 Pro模拟器上运行;macOS和iOS 26.5的输出完全相同,所有输出均如表所示。容量探测:URL(fileURLWithPath: NSHomeDirectory()).resourceValues(forKeys: [.volumeAvailableCapacityKey, .volumeTotalCapacityKey, .volumeAvailableCapacityForImportantUsageKey])加statfs;模拟器运行输出volumeAvailableCapacity = 226009026560、f_bavail = 55177985、f_bsize = 4096;宿主运行输出volumeAvailableCapacity = 226009079808、f_bavail = 55177998。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple,HealthKit文档,earliestAuthorizedSampleDate(for:)和Authorizing access to health data,2026年9月15日获取。方法页面列出的可用性为iOS 27.0、iPadOS 27.0、Mac Catalyst 27.0、macOS 27.0、visionOS 27.0和watchOS 27.0,是关于结束日期那句话以及“Your app can’t distinguish between denied and full access; limited authorization is the only state your app can identify, by design.”的来源;指南是“people can choose to grant your app access to only a limited window of recent data rather than their full history”、关于第二个界面那句话以及“Time-bound authorization applies only to sample types.”的来源。 ↩↩↩↩↩
-
Apple,MXMetricManager,MetricKit类参考,2026年9月15日通过Apple的文档JSON获取:可用性列出iOS 13.0、iPadOS 13.0、Mac Catalyst 13.1、macOS 12.0和visionOS 1.0,每一项的
deprecatedAt均为27.0,弃用摘要为“Use MetricManager instead.”。 ↩