【问题标题】:iOS Document folder is not a directory and/or is missingiOS 文档文件夹不是目录和/或丢失
【发布时间】:2018-05-02 11:09:25
【问题描述】:

尝试归档 Codable 元素的数组。

do {
   let data = try PropertyListEncoder().encode(elements)
   let success = NSKeyedArchiver.archiveRootObject(data, toFile:self.archiveURL.path)
   print(success ? "Successful save" : "Save Failed")
} catch {
   print("Save Failed")
}

由于某种原因,路径 (archiveURL) 经常出错:

let archiveURL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!

总是返回这样的 URL:

file:///Users/userName/Library/Developer/CoreSimulator/Devices/deviceID/data/Documents

但是通过文件夹搜索我没有看到 /Documents 文件夹。最近有什么变化吗?它曾经在几周前工作(非常肯定)。超级烦人,我找不到任何解决方法/解决方法。

【问题讨论】:

    标签: ios swift nsfilemanager nskeyedarchiver


    【解决方案1】:

    我相信这是 iOS 模拟器的一个(新的)“功能” - 最初安装应用程序时,并非所有常用目录都存在。

    幸运的是,创建它们很容易,例如对于 applicationSupport 目录,我在我的应用程序中执行此操作:

    let fileManager = FileManager.default
    let directory = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first!
    if !fileManager.fileExists(atPath: directory) {
      try fileManager.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
    }
    

    【讨论】:

    • Documents 确实存在,框架隐式创建目录。而NSSearchPathForDirectoriesInDomains 已过时,请使用let directory = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)。如果目录不存在,它会创建目录。
    • @vadian 事情是这个目录不存在,但我最终以你的方式创建目录:)
    • 我也遇到过这个问题,它在我的 CI 服务器上造成了一些非常烦人的错误。你知道Apple是否记录了这些目录不保证存在?
    【解决方案2】:

    这发生在运行 iOS 11.x 及更高版本的模拟器中。

    在 iOS 11 之前,模拟器在启动时会创建全局(独立于应用程序)的 Documents 文件夹。从 iOS 11.x 开始(不知道是不是特别点的版本),就不会再出现这种情况了。

    请注意NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first 仅在(单元)测试中返回此全局文档路径,而不是在运行应用程序时返回。如果您运行应用程序,您将获得应用程序特定的 Documents 文件夹,该文件夹在模拟器中安装应用程序时仍会创建。

    这似乎是苹果方面的一个错误。如果您遇到此问题(您似乎遇到过),请在https://developer.apple.com/bug-reporting/ 提交错误报告。

    【讨论】:

      【解决方案3】:

      您不能(覆盖)写入Documents 目录,您必须附加一个文件名。

      您为什么要归档数据?您可以将属性列表数据直接写入磁盘。

      并且从不catch子句中打印无意义的文字字符串,至少打印实际错误。

      let fileName = "myPropertyList.plist"
      let fileURL = archiveURL.appendingPathComponent(fileName)
      do {
         let data = try PropertyListEncoder().encode(elements)
         try data.write(to: fileURL)
      } catch {
         print("Save Failed", error)
      }
      

      【讨论】:

      • 感谢您的快速响应和提示 1) 我不想实际覆盖 Documents,尤其是 它不存在 所以我猜还是(附加文件名)该 URL 将无用,因为 write 不会创建文件
      • 试试吧!它应该工作。 write确实创建文件。
      猜你喜欢
      • 1970-01-01
      • 2017-08-31
      • 2016-07-02
      • 1970-01-01
      • 2017-11-05
      • 2013-08-06
      • 2016-06-23
      • 2022-11-22
      • 2011-11-01
      相关资源
      最近更新 更多