首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >尝试使用FileManager复制文件时出错:不允许操作

尝试使用FileManager复制文件时出错:不允许操作
EN

Stack Overflow用户
提问于 2020-12-22 18:10:41
回答 1查看 998关注 0票数 2

我是FileManager in iOS的新手。我试图创建一个简单的应用程序:有一个文件列表,当用户按下一个单元格时,文件就会打开。用户还可以添加新文件。

不久前,我提出一个问题了另一个错误,我得到了一个回答模拟器上的工作,但它不能在真正的设备上工作!

我的代码:(错误在storeAndShare()中)

代码语言:javascript
运行
复制
typealias UrlLink = String

extension UrlLink {
var url: URL {
    var url = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    url.appendPathComponent(self)
    return url
}
}

class TableViewController: UITableViewController, UIDocumentPickerDelegate {

var names: [UrlLink] = []

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
     self.navigationItem.rightBarButtonItem = self.editButtonItem
}

func urlForFilename(_ filename: String) -> URL {
    var url = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    url.appendPathComponent(filename)
    return url
}

@IBAction func newButtonPressed(_ sender: Any) {
    let types = UTType(tag: "pdf", tagClass: .filenameExtension, conformingTo: nil)!
    let controller = UIDocumentPickerViewController(forOpeningContentTypes: [types])
    controller.delegate = self
    self.present(controller, animated: true, completion: nil)
}

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
    for url in urls {
        self.storeAndShare(withURL: url)
    }
}

// MARK: - Table view data source

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let removedName = self.names.remove(at: indexPath.row)
        do {
            try FileManager.default.removeItem(atPath: removedName.url.path)
        } catch let err {
            print("Error while trying to remove the file \(err)")
        }
        
        tableView.deleteRows(at: [indexPath], with: .automatic)
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return names.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

    cell.textLabel?.text = names[indexPath.row]
    
    if FileManager.default.fileExists(atPath: names[indexPath.row].url.path) {
        cell.accessoryType = .disclosureIndicator
    } else {
        cell.accessoryType = .none
    }

    return cell
}

lazy var documentInteractionController: UIDocumentInteractionController = {
    let vc = UIDocumentInteractionController()
    vc.delegate = self
    return vc
}()

func getSelf() -> TableViewController {
    return self
}

func share(url: URL) {
    documentInteractionController.url = url
    documentInteractionController.uti = url.typeIdentifier ?? "public.data, public.content"
    documentInteractionController.name = url.localizedName ?? url.lastPathComponent
    documentInteractionController.presentPreview(animated: true)
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    share(url: self.names[indexPath.row].url)
}

func storeAndShare(withURL url: URL) {

    let directoryURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    var newURL = directoryURL.appendingPathComponent(url.lastPathComponent)
    
    var index = 1
    let originalNewURL = newURL
    while FileManager.default.fileExists(atPath: newURL.path) {
        newURL = originalNewURL
        let comp: NSString = newURL.lastPathComponent as NSString
        newURL.deleteLastPathComponent()
        let newName: String = "\(comp.deletingPathExtension) \(index).\(comp.pathExtension)"
        newURL.appendPathComponent(newName)
        index = index + 1
    }
    
    do {
        try FileManager.default.copyItem(at: url, to: newURL)
        DispatchQueue.main.async { [self] in
            names.append(newURL.lastPathComponent)
            tableView.insertRows(at: [IndexPath(row: names.count - 1, section: 0)], with: .automatic)
        }
    } catch {
        print("ERROR: \(error).") // ERROR: Error Domain=NSCocoaErrorDomain Code=257 "The file “I am a file and you put documents in me.pdf” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/תיקיות/I am a file and you put documents in me.pdf, NSUnderlyingError=0x281ab2790 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}.
    }
}

}

extension TableViewController: UIDocumentInteractionControllerDelegate {
/// If presenting atop a navigation stack, provide the navigation controller in order to animate in a manner consistent with the rest of the platform
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
    guard let navVC = self.navigationController else {
        return self
    }
    return navVC
}
}
extension URL {
var typeIdentifier: String? {
    return (try? resourceValues(forKeys: [.typeIdentifierKey]))?.typeIdentifier
}
var localizedName: String? {
    return (try? resourceValues(forKeys: [.localizedNameKey]))?.localizedName
}
}

基本上,当用户添加一个新文件时,我的应用程序试图将其复制到documents文件夹中,以便将其存储在那里。

当试图将选定的文件复制到documents文件夹时,我得到了以下错误:

错误Domain=NSCocoaErrorDomain Code=257“文件”I是一个文件,您将文档放在me.pdf中“无法打开,因为您没有查看它的权限”。UserInfo={NSFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/תיקיות/I是一个文件,您将文档放入me.pdf,NSUnderlyingError=0x281ab2790 {Error Domain=NSPOSIXErrorDomain Code=1“不允许操作”}

我似乎没有查看文件的权限。但这很奇怪,因为我刚刚选择了带有UIDocumentInteractionController的文件,正如我前面所说的,它在模拟器上运行得很好。

如何获得复制文件的许可?提前谢谢!

EN

回答 1

Stack Overflow用户

发布于 2021-08-16 00:48:53

我也遇到了同样的问题,按照@Cameron的回答这里

简而言之,您所需要做的就是包装处理文件的代码部分,如下所示:

代码语言:javascript
运行
复制
func readFile(url: URL){
    // `url` to the directory or file you are trying to access.
    url.startAccessingSecurityScopedResource()

    // deal with your file here

    url.stopAccessingSecurityScopedResource()
}

苹果官方文件

就你而言,应该是:

代码语言:javascript
运行
复制
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

    cell.textLabel?.text = names[indexPath.row]

    // newly added    
    names[indexPath.row].url.startAccessingSecurityScopedResource()

    if FileManager.default.fileExists(atPath: names[indexPath.row].url.path) {
        cell.accessoryType = .disclosureIndicator
    } else {
        cell.accessoryType = .none
    }
    // newly added
    names[indexPath.row].url.stopAccessingSecurityScopedResource()

    return cell
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65413740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档