NSCocoaErrorDomain 代码=257 文件权限

Posted

技术标签:

【中文标题】NSCocoaErrorDomain 代码=257 文件权限【英文标题】:NSCocoaErrorDomain Code=257 File Permission 【发布时间】: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
    

【问题讨论】:

【参考方案1】:

我也遇到过问题。如果您查看文档的 URL,您可以尝试:

url.startAccessingSecurityScopedResource()

如果返回 true,您还需要调用:

url.stopAccessingSecurityScopedResource()

【讨论】:

以上是关于NSCocoaErrorDomain 代码=257 文件权限的主要内容,如果未能解决你的问题,请参考以下文章

错误域=NSCocoaErrorDomain 代码=3840 “无值。” UserInfo=NSDebugDescription=无值。

错误域 = NSCocoaErrorDomain 代码 = 3840 “无值。” UserInfo=NSDebugDescription=无值。

错误域 = NSCocoaErrorDomain 代码 = 3840 “字符周围的值无效

iOS swift 中的错误域 = NSCocoaErrorDomain 代码 = 3840?

Json 错误:错误域 = NSCocoaErrorDomain 代码 = 3840“无值”。 UserInfo=NSDebugDescription=无值。

错误域=NSCocoaErrorDomain 代码=3840 JSONObject