macos应用沙盒是内核强制执行的运行时约束体系,默认仅允许访问自身容器目录和临时目录;访问其他路径须经用户授权、安全作用域资源访问及书签持久化,并需正确配置entitlements与info.plist权限声明。

macOS 应用沙盒不是“打开开关就能用”的功能,而是由内核强制执行的运行时约束体系。它不依赖开发者自觉,也不靠用户授权绕过——所有越界访问都会被系统拦截,并返回 Operation not permitted 错误。
沙盒默认允许访问的位置
启用沙盒后,应用天然拥有读写权限的路径仅有两个:
- 自身容器目录:
~/Library/Containers/<bundle-id>/Data/</bundle-id>(含 Documents、Caches、Preferences 等子目录) - 临时目录:
~/Library/Containers/<bundle-id>/Data/tmp/</bundle-id>
其他任何路径——包括 ~/Documents、~/Desktop、/Applications,甚至其他应用的容器目录——均被禁止直接访问。
合法访问用户文件夹的完整流程
不能硬编码路径去 open() 或 write(),必须走用户授权 + 凭证管理闭环:
- 用
NSOpenPanel弹出系统对话框,设置canChooseDirectories = true,由用户手动选择目标文件夹 - 调用
url.startAccessingSecurityScopedResource()开启本次访问权限 - 完成读写后,立即调用
url.stopAccessingSecurityScopedResource() - 若需重启后仍可访问,调用
url.bookmarkData(options: .withSecurityScope)生成书签数据,并存入自身容器内(如Application Support目录) - 下次启动时,用
URL.resolvingBookmarkData(_:)恢复 URL,并再次startAccessing
权限配置与 entitlements 关键项
仅写代码不够,Xcode 中必须同步完成三项声明:
-
com.apple.security.app-sandbox设为true(开启沙盒的基础前提) -
com.apple.security.files.user-selected.read-write(对应 Xcode Capabilities 中勾选 “User Selected File Access”) -
com.apple.security.files.bookmarks.app-scope(若使用书签持久化,必须启用 App Sandbox Bookmarks)
联网行为也需明确声明:com.apple.security.network.client(出站)、com.apple.security.network.server(监听),temporary-exception 类权限不可用于发布版本。
常见失败原因与规避要点
多数报错源于配置与代码逻辑脱节:
- Info.plist 或 entitlements 文件缺失对应权限键值
- 忘记
start/stop配对,或在异步操作中未确保 stop 被调用 - 把 bookmarkData 存到非沙盒路径(如
/tmp或全局路径),导致重启后无法读取 - 未检查
isStale返回值,使用已失效的书签触发权限拒绝 - 访问照片库、通讯录等敏感资源时,缺少对应的
NSPhotoLibraryUsageDescription等 Info.plist 描述字段











