【问题标题】:How to copy selected file to app's directory如何将选定的文件复制到应用程序的目录
【发布时间】:2021-04-01 02:27:25
【问题描述】:

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

这是我目前拥有的:

class TableViewController: UITableViewController, UIDocumentPickerDelegate {

var urls: [URL] = []

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
}

@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 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 urls.count
}

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

    cell.textLabel?.text = urls[indexPath.row].localizedName

    return cell
}

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

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.urls[indexPath.row])
}

func storeAndShare(withURL url: URL) {
    /// START YOUR ACTIVITY INDICATOR HERE
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else { return }
        let direcotryURL = URL(string: FileManager.default.currentDirectoryPath)!
        let newURL = direcotryURL.appendingPathComponent(response?.suggestedFilename ?? "fileName.pdf")
        
        do {
            try data.write(to: newURL)
        } catch let err {
            print("ERROR: \(err).")

            // Error Domain=NSCocoaErrorDomain Code=518 "The file couldn’t be saved because the specified URL type isn’t supported." UserInfo={NSURL=/doc.pdf}

            return
        }
        
        DispatchQueue.main.async {
            /// STOP YOUR ACTIVITY INDICATOR HERE
            self.urls.append(newURL)
            self.share(url: newURL)
            self.tableView.reloadData()
        }
        }.resume()
}

}

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
}
}

storeAndShare() 函数有问题。我正在尝试将所选文件复制到应用程序的目录,然后将新 URL 添加到 url 列表 (self.urls)。 但它不起作用,并且在 data.write 中给我一个错误:

Error Domain=NSCocoaErrorDomain Code=518 "无法保存文件,因为不支持指定的 URL 类型。" UserInfo={NSURL=/doc.pdf}

为什么会这样?我怎样才能达到我所需要的?提前致谢

【问题讨论】:

  • 你为什么使用URLSession?你发现它的用途了吗?
  • 不,正如我所说,我对此真的很陌生。我的大部分代码都被复制了

标签: ios swift url file-manager


【解决方案1】:

最严重的错误是currentDirectoryPath。您不得使用它来获取 Documents 目录的路径。您必须致电url(for:in:appropriateFor:create:urls(for:in:)FileManager

而且——如果我们谈论的是本地文件——URLSession 也是错误的方式。

func storeAndShare(with url: URL) {

    let directoryURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let newURL = directoryURL.appendingPathComponent(url.lastPathComponent)
    
    do {
        try FileManager.default.copyItem(at: url, to: newURL)
        DispatchQueue.main.async {
            self.urls.append(newURL)
            self.share(url: newURL)
            self.tableView.reloadData()
        }
    } catch {
        print("ERROR: \(error).")
    }
}

【讨论】:

  • 放置它而不是我当前的函数,它在第二行给我一个错误:Cannot find 'response' in scope
【解决方案2】:

"/doc.pdf"

对你来说是不可写的。

获取文档目录:

let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]

并将您的文件保存在那里(而不是使用currentDirectoryPath)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    • 2011-12-10
    相关资源
    最近更新 更多