【发布时间】:2021-08-30 18:58:15
【问题描述】:
在尝试使用包装 UIDocumentPickerViewController 的 UIViewControllerRepresentable 在 Swift UI 应用程序中获取文件时,我遇到了一个非常奇怪的行为:
在模拟器上运行应用程序按预期工作。但是,在物理设备上运行应用程序不会返回文件。相反,它会抛出以下错误:Error Domain=NSCocoaErrorDomain Code=257 "无法打开文件“grile.doc”,因为您无权查看它。"
调试,我设法发现导致物理设备上抛出此错误的代码块不是对文件的实际访问,而是试图获取抛出的文件大小。
我在这里做错了什么,这使得 Representable 在模拟器上工作得很好,但在物理设备上却不能工作?
我已经尝试使用 FileManager 方法来获取文件大小,同样的事情发生了。我还尝试使用 FileManager 将文件复制到临时位置,这也会引发相同的错误。
import Foundation
import SwiftUI
import UniformTypeIdentifiers
struct FilePicker: UIViewControllerRepresentable {
// MARK: - Properties
var didPickFileURL: ((URL) -> Void)
var didPickFileOverFileSizeLimit: (() -> Void)
// MARK: - UIViewController Wrapper Methods
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType("public.item")!])
picker.allowsMultipleSelection = false
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
return FilePicker.Coordinator(parent: self)
}
// MARK: - Coordinator
class Coordinator: NSObject, UIDocumentPickerDelegate {
// MARK: - Coordinator Properties
var parent: FilePicker
// MARK: - Coordinator Init
init(parent: FilePicker) {
self.parent = parent
}
// MARK: - Coordinator UIDocument Delegate
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let url = urls.first else { return }
do {
let resources = try url.resourceValues(forKeys:[.fileSizeKey])
let fileSize = Double(resources.fileSize!)
// check if the file size is bigger than the limit per attachment
if fileSize.convertBytesToMegabytes() < 10 {
self.parent.didPickFileURL(url)
} else {
self.parent.didPickFileOverFileSizeLimit()
}
} catch {
print("Error: \(error)")
}
}
}
}
转换扩展:
extension Double {
func convertBytesToMegabytes() -> Double {
let kilobytes = self / 1024
let megabytes = kilobytes / 1024
return megabytes
}
}
【问题讨论】: