Mac Catalyst 的 UIDocumentPickerViewController 配置

问题描述

在 Mac Catalyst 中使用 UIDocumentPickerViewController 时,是否需要其他功能、权限或沙盒配置?我错过了一个警告吗?

在带有 Catalyst 的 macOS (11.4) 上运行以下代码,选择文件时永远不会调用 didPickDocumentsAt: 委托函数。但是,如果选择器被关闭或尝试打开文件,则会调用 documentPickerWasCancelled

我最初怀疑由于 SwiftUI 的 View struct recreation 不正确的内容类型或委托解除分配,但当调用 as cancel 时,我怀疑不是。

需要注意的是,在为 macOS 配置 ascopy 而为 iOS 配置 false 时,UIDocumentPickerViewController 必须为 true

错误表示沙箱权限错误

DocumentPickerSwiftUI[42570:1472986] Failed to create an FPSandBoxingURLWrapper for file:///Users/ed/test_file.txt. Error: Error Domain=NSPOSIXErrorDomain Code=1 "Couldn't issue sandBox extension com.apple.app-sandBox.read-write for '/Users/ed/test_file.txt': Operation not permitted" UserInfo={NSDescription=Couldn't issue sandBox extension com.apple.app-sandBox.read-write for '/Users/ed/test_file.txt': Operation not permitted}

当前能力配置(用户选择文件的只读访问):

Capabilities screenshot

import SwiftUI
import UIKit
import UniformTypeIdentifiers

struct ContentView: View {
    @State var showDocumentPicker: Bool = false

    var body: some View {
        documentPickerButton
    }

    private var documentPickerButton: some View {
        Button(action: {
            showDocumentPicker.toggle()
        },label: {
            Text("Open")
        })
        .sheet(isPresented: self.$showDocumentPicker) {
            AudioFilePicker()
        }
    }
}

final class AudioFilePicker: UIViewControllerRepresentable {

    var viewController = UIDocumentPickerViewController(foropeningContentTypes: [.item],ascopy: false)

    class Coordinator: NSObject,UIDocumentPickerDelegate {

        var parent: AudioFilePicker

        init(parent: AudioFilePicker) {
            self.parent = parent
        }

        func documentPicker(_ controller: UIDocumentPickerViewController,didPickDocumentsAt urls: [URL]) {
            print("Picker Loaded: \(String(describing: urls.first?.absoluteString))")
            // Do something with URL (never called)
        }

        func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
            print("Picker Cancelled")
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
        viewController.delegate = context.coordinator
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController,context: Context) { }
}

解决方法

该错误确实表示权限错误。尝试添加:

USERID     Clicks       Pageload
U100003     2              1
U100005     Nan            1
U100008      22            20