You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac Catalyst下UIDocumentPickerViewController沙箱配置与回调异常问题

问题解决方案

错误根源

你遇到的didPickDocumentsAt不触发问题,是沙箱权限不匹配导致:当前你配置的是用户选中文件只读权限,但系统默认尝试为选中文件申请读写沙箱扩展,权限申请被拒绝后回调直接中断,只有取消操作不受权限影响可以正常触发。

修复步骤

  1. 调整沙箱权限配置
    打开项目Signing & Capabilities中的App Sandbox配置,将「User Selected File」的权限从「Read Only」改为Read/Write,匹配系统默认的扩展申请要求。

  2. 修正AudioFilePicker实现错误
    不要将UIDocumentPickerViewController作为存储属性提前初始化,SwiftUI视图刷新时会导致实例上下文异常,正确实现需要将初始化逻辑移到makeUIViewController方法内:

    final class AudioFilePicker: UIViewControllerRepresentable {
        class Coordinator: NSObject, UIDocumentPickerDelegate {
            var parent: AudioFilePicker
            init(parent: AudioFilePicker) {
                self.parent = parent
            }
            func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
                guard let url = urls.first else { return }
                // Mac Catalyst下必须开启安全域访问才能读取文件
                let hasAccess = url.startAccessingSecurityScopedResource()
                defer {
                    if hasAccess {
                        url.stopAccessingSecurityScopedResource()
                    }
                }
                print("Picker Loaded: \(url.absoluteString)")
                // 后续文件处理逻辑
            }
            func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
                print("Picker Cancelled")
            }
        }
        func makeCoordinator() -> Coordinator {
            return Coordinator(parent: self)
        }
        func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
            // 跨平台适配asCopy参数
            #if targetEnvironment(macCatalyst)
            let asCopy = false
            #else
            let asCopy = true
            #endif
            let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.item], asCopy: asCopy)
            picker.delegate = context.coordinator
            return picker
        }
        func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) { }
    }
    
  3. 可选只读权限适配
    如果你确实只需要读取文件不需要写入权限,不需要修改沙箱权限,只需要在初始化picker后添加以下配置,告知系统仅申请读权限:

    picker.allowsWriting = false
    

其他注意事项

  • 每次修改沙箱权限后需要清理Xcode构建缓存(Shift+Command+K)再运行,避免旧配置缓存导致验证失败
  • 所有通过文档选择器拿到的URL,都必须调用startAccessingSecurityScopedResource()开启安全域访问,使用完成后调用停止方法,否则会出现无权限读取文件的问题

内容的提问来源于stack exchange,提问作者NSGoat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 09:36:04