根本原因是沙盒机制禁止未经用户显式授权访问任意外部路径,包括SMB/NFS共享、VMware共享文件夹及外接卷;必须通过NSOpenPanel由用户选择路径、生成并持久化安全书签,并在Info.plist和entitlements中声明com.apple.security.files.user-selected.read-write权限。

macOS 应用在沙盒环境下无法访问共享目录,根本原因不是权限配置错误或路径写错,而是沙盒机制本身禁止应用未经用户显式授权就访问任意外部路径——包括 SMB/NFS 网络共享、VMware 共享文件夹、甚至本地挂载的外接卷(如 /Volumes/NO NAME)。
沙盒默认不放行任何共享路径
沙盒应用启动后,仅能自由读写自身容器(~/Library/Containers/xxx)和系统明确允许的有限位置(如临时目录)。所有其他路径,无论是否已挂载、是否有 POSIX 权限,都受 TCC(透明性、同意与控制)和沙盒 entitlements 双重拦截:
- 网络共享(SMB/AFP)挂载点(如
/Volumes/MyServer)属于“用户选中之外的任意路径”,沙盒默认拒绝访问 - VMware 或 Parallels 的共享文件夹,在 macOS 视为普通挂载卷,同样无豁免权
- 即使你用
sudo chmod -R 777修改挂载点权限,Operation not permitted错误仍会出现——这是内核级拦截,与文件系统权限无关
必须通过用户主动选择触发授权
要让沙盒应用访问共享目录,唯一合规路径是让用户亲手选中该路径,而非硬编码或自动挂载后直接访问:
- 首次使用时,调用
NSOpenPanel并设置canChooseDirectories = true,引导用户点击进入/Volumes/MyShare或其子文件夹 - 选中后立即调用
url.startAccessingSecurityScopedResource(),并在操作完成后严格配对stopAccessing - 生成安全书签(
url.bookmarkData(options: .withSecurityScope)),存入自身容器内的Application Support目录,下次启动才能恢复访问
Info.plist 和 entitlements 必须匹配启用
缺少任一声明,即使用户点了授权,后续访问也会失败:
-
Info.plist中需明确添加:<key>com.apple.security.files.user-selected.read-write</key><true/> - entitlements 文件中对应项也必须为
true;Xcode Capabilities 中勾选 “User Selected File Access” 可自动生成,但需手动验证 - 若共享目录含敏感内容(如照片库子集),还需额外声明
com.apple.security.assets.photos等专项权限
常见误判与绕过陷阱
开发者常误以为以下方式可行,实际均违反沙盒原则且无法上架:
- 用
temporary-exception或absolute-path.read-only权限硬编码挂载路径——Mac App Store 审核直接拒收 - 尝试在后台静默挂载并访问共享目录——沙盒不允许无用户交互的持久化访问
- 把安全书签存在
/tmp或~/Documents——沙盒应用无权读取这些位置,书签加载即失败


















