Highlight
macOS 27 扩展了 Automatic Assessment Configuration 框架,让教育考试 App 可以通过单一 API 配置系统级安全检查、辅助功能限制、Menu Bar/Dock 定制、文件访问白名单和进程管控,不再需要自行编写拦截代码。
核心内容
考前设备状态检查
(00:40)
组织一场在线考试,最怕学生在考前把系统改得面目全非。SIP 关了、MDM 卸了、开了 Lockdown Mode 把网络监控拦在外面——这些都会让考试环境变得不可信。
以前开发者只能自己写脚本去检查这些状态,检查逻辑和系统版本强耦合,macOS 一升级就失效。
macOS 27 把这类检查收进了 AEAssessmentConfiguration。你设置几个布尔属性,系统在考试开始前自动验证。不满足条件时直接弹窗告诉学生该修什么,不用你写一行 UI 代码。
辅助功能:默认保留,按需限制
(03:00)
考试软件最容易犯的错误,是一刀切关掉所有辅助功能。VoiceOver、Switch Control 这些对残障学生是刚需,关掉等于剥夺考试权利。
AAC 框架的做法是反过来的:默认保留学生已开启的辅助功能,开发者显式指定哪些要禁用。allowsAccessibilitySwitchControl = true 不会帮学生打开这个功能,只是允许已开启的学生继续使用。把无障碍从”考完再补”变成”从第一天就设计进去”。
系统体验定制:白名单思路
(05:07)
Mac 用户习惯了 Menu Bar 和 Dock。以前考试软件为了防作弊,喜欢搞一个全屏无边框窗口把系统 UI 全挡住,学生连看时间、调音量都找不到入口。
Apple 这次不搞一刀切,而是给了一套白名单 API。你可以精确控制 Menu Bar 显示哪些图标、Apple 菜单保留哪些项、Dock 是否显示。系统原生渲染,不用你自己画假 UI。
进程管控:只让信任的进程跑
(09:16)
后台跑着的 Safari、Notes、Shortcuts 都可能成为作弊通道。截图、录屏、自动脚本,这些都不该在考试期间存在。
allowOnlyParticipantsToRun = true 让系统在考试开始时自动终止所有非白名单进程。配合 allowsUserScriptExecution = false 封杀 Shortcuts 和 Automator,考试环境从”App 层防御”升级到”系统层防御”。
详细内容
系统前提条件检查
(02:30)
AEAssessmentConfiguration 提供六项系统级预检:
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowLockdownMode = false
configuration.allowPrivateRelay = false
configuration.requiresSIP = true
configuration.requiresManagedDevice = true
configuration.requiresSingleUser = true
configuration.requiresUserAccountType = .standard
return configuration
}
关键点:
requiresSIP:要求系统完整性保护(System Integrity Protection)已开启,防止底层系统被篡改requiresManagedDevice:要求设备通过 MDM 托管,适用于学校统一配发的设备requiresSingleUser:要求只有一个用户账户登录,防止多账户切换作弊requiresUserAccountType:限制账户类型为.standard(标准用户),排除管理员账户allowLockdownMode:设为false要求关闭锁定模式,避免其拦截考试所需的网络监控allowPrivateRelay:设为false要求关闭 iCloud 专用代理,确保网络流量可被审计
如果学生设备不满足任一条件,系统会自动弹出提示,列出所有需要修复的问题。
辅助功能限制
(04:01)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowsAccessibilityVoiceOver = true
configuration.allowsAccessibilitySwitchControl = false
configuration.allowsAccessibilityAlternativeInputMethods = true
configuration.allowsAccessibilityBackgroundSounds = true
configuration.allowsAccessibilityHoverText = true
configuration.allowsAccessibilityLiveSpeech = true
configuration.allowsAccessibilitySpokenContent = true
configuration.allowsAccessibilityVoiceControl = true
configuration.allowsAccessibilityZoom = true
return configuration
}
关键点:
- 每个
allowsAccessibility前缀的属性控制一项具体辅助功能 - 设为
true表示”允许已开启的学生继续使用”,不会主动帮学生打开 - 设为
false会在考试开始时自动退出该功能,且学生在考试期间无法重新启动 - Switch Control 被禁用是因为它可以录制和回放自定义操作序列,存在作弊风险
- VoiceOver、Zoom、Hover Text 等视觉辅助功能默认建议保留,确保视障学生能正常参与
Menu Bar 和 Apple 菜单定制
(05:32)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowsMenuBar = true
configuration.allowedMenuBarItems = [
.battery,
.clock,
.volume
]
configuration.allowedAppleMenuItems = [
.sleep
]
return configuration
}
关键点:
allowsMenuBar = true启用 Menu Bar 显示,默认隐藏allowedMenuBarItems是白名单,只有列表中的系统图标会保留- 白名单中的图标不会”强制显示”,如果学生本来就没在 Menu Bar 添加该图标,它不会出现
allowedAppleMenuItems控制点击左上角 Apple 图标后的菜单内容- 传入空数组会隐藏所有 Apple 菜单项,只保留”关于本机”
输入方法限制
(07:01)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowsDictation = false
configuration.allowsAutoFill = false
configuration.allowsStructuralInput = false
configuration.allowsEmojiKeyboard = false
return configuration
}
关键点:
allowsDictation:听写功能可能自动纠正拼写,为考生提供”免费”答案allowsAutoFill:自动填充会从通讯录等来源预加载信息,可能泄露参考资料allowsStructuralInput:结构性输入会暴露字符组合规则,可能泄露答案线索allowsEmojiKeyboard:表情符号键盘带搜索功能,可作为传递暗号的通道- 这些限制会同时隐藏对应的菜单项,并阻止在支持它们的 UI 控件中使用
Dock 和文件系统访问
(07:38)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowsDock = true
return configuration
}
(08:35)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowedDirectoriesAndFiles = [
URL(fileURLWithPath: "~/Documents/")
]
return configuration
}
关键点:
allowsDock = true显示 Dock,但只渲染考试允许的 App,Finder 和 Trash 始终存在- Finder 即使出现在 Dock 中,也需要显式添加为 participant 才能交互
allowedDirectoriesAndFiles同时作用于标准 Open/Save 面板和 Finder 窗口- 学生保存文件时,Save 面板只显示白名单目录,无法浏览到其他位置
进程和脚本限制
(09:58)
import AutomaticAssessmentConfiguration
func makeAssessmentConfiguration() -> AEAssessmentConfiguration {
let configuration = AEAssessmentConfiguration()
configuration.allowOnlyParticipantsToRun = true
configuration.allowsUserScriptExecution = false
return configuration
}
关键点:
allowOnlyParticipantsToRun = true:考试开始时系统终止所有非白名单进程,只保留主考试 App、显式添加的 participant App 和必要系统进程allowsUserScriptExecution = false:阻止 Shortcuts 和 Automator 脚本执行- Safari、Notes 等后台 App 会在考试开始时自动退出
- 如果考试依赖第三方组件(如防作弊摄像头插件),必须先将其加入 participant 白名单
最佳实践
(10:51)
- 用框架 API 替代自己写的拦截代码。
CGEventTap、隐藏窗口遮罩这些”祖传代码”可以删了 - 从宽松开始,按需收紧。过度限制会影响考生体验
- 把无障碍当刚需设计,不是考完再补
- 注册 transition callback,根据系统回调驱动 App 状态,不要假设调用 begin/end 就立即生效
- 每个 macOS beta 发布当天就测试,发现问题立刻提 Feedback
核心启发
做一个”一键开考”的教育 App
做什么:考试开始前,App 自动检测设备状态、配置环境、锁定系统。考生只需要点击”开始考试”,所有安全检查和环境配置由 AAC 框架自动完成。
为什么值得做:以前开发者要自己写脚本检查 SIP、MDM、Lockdown Mode 等状态,检查逻辑和系统版本强耦合,macOS 一升级就失效。AAC 框架把这类检查标准化,不满足条件时自动弹窗提示修复。
怎么开始:创建 AEAssessmentConfiguration,设置 requiresSIP、requiresManagedDevice、allowLockdownMode 等属性,调用 begin 启动考试会话。
给残障学生做定制化的考试辅助
做什么:利用辅助功能的细粒度控制,为不同需求的学生生成不同的配置模板。视障学生保留 VoiceOver 和 Zoom,运动障碍学生保留 Switch Control,其他可能作弊的功能则禁用。
为什么值得做:一刀切关掉所有辅助功能等于剥夺残障学生的考试权利。AAC 框架默认保留学生已开启的辅助功能,开发者只禁用有作弊风险的具体项,把无障碍从”考完再补”变成”从第一天就设计进去”。
怎么开始:按学生档案动态生成 AEAssessmentConfiguration,设置 allowsAccessibilityVoiceOver、allowsAccessibilitySwitchControl 等属性,为不同需求的学生加载对应模板。
做一个考试环境监控面板
做什么:在教师端做一个实时监控面板,显示每个考生的设备状态:SIP 是否开启、是否有未授权进程在跑、哪些辅助功能被启用。
为什么值得做:监考老师无法逐个检查学生设备,远程考试时更是如此。利用 AAC 框架的预检能力,把设备合规状态实时上报给监考系统,异常设备自动告警。
怎么开始:在考试 App 中集成 AAC 预检逻辑,将检查结果通过 WebSocket 或轮询 API 上报到教师端,在仪表板上用红黄绿灯标识设备状态。
做一个安全的离线考试模式
做什么:利用 allowOnlyParticipantsToRun 和文件系统白名单,做一个完全离线的考试环境。考试期间学生只能访问指定的本地资源。
为什么值得做:后台跑着的 Safari、Notes、Shortcuts 都可能成为作弊通道。进程管控把考试环境从”App 层防御”升级到”系统层防御”,自动终止所有非白名单进程。
怎么开始:设置 allowOnlyParticipantsToRun = true 和 allowsUserScriptExecution = false,配合 allowedDirectoriesAndFiles 限制文件访问范围,将考试依赖的第三方组件加入 participant 白名单。
迁移旧版考试软件的拦截代码
做什么:把 CGEventTap、隐藏窗口遮罩这些”祖传代码”替换为 AAC 框架的标准 API。
为什么值得做:自己写的拦截代码容易和系统更新冲突,维护成本高。AAC 框架是系统级实现,稳定性和兼容性更有保障,代码也更简洁。
怎么开始:识别项目中所有自定义的键盘拦截、窗口遮挡、进程监控逻辑,逐步替换为对应的 AEAssessmentConfiguration 属性,删除不再需要的底层 hack。
关联 Session
- What’s new in Device Management — MDM 托管设备与考试预检的关系
- What’s new in accessibility controls — 辅助功能限制的底层机制
- What’s new in App Intents — Shortcuts 限制与 App Intents 的交互
- What’s new in Swift — 配置 API 的 Swift 接口设计
评论
GitHub Issues · utterances