iOS 11上的UIDocument创建:不允许读者访问该URL

时间:2018-01-01 12:30:22

标签: ios ios11 uidocument uti document-based

自iOS 11以来,我每次使用UIDocument API创建新文档时都遇到以下错误

  

[错误]无法获取商品 / var / mobile / Containers / Data / Application / XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX / Documents / myDoc-XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX的属性值.myFile(n)

     

错误:错误域= NSFileProviderInternalErrorDomain代码= 1
  "不允许读者访问该网址。"
  UserInfo = {NSLocalizedDescription =不允许读者访问该URL。}

与SO上的类似问题(123)不同,我没有使用UIDocumentBrowserViewController。我只是创建一个UIDocument并自己调用save()Documents目录。我发现的closest question使用UIManagedDocument。但是,在我的情况下,尽管出现错误消息,仍然可以成功创建和写入文件。

这是我保存程序的要点:

@IBAction func createDoc(_ sender: Any) {
    let uuid = UUID().uuidString
    let doc = Document(baseName: "myDoc-\(uuid)")
    doc.save(to: doc.fileURL, for: .forCreating) { (completed) in
        if (completed) {
            doc.close(completionHandler: nil)
            self.verifyNumberOfFiles()
        }
    }
}

为了简化这个问题,我的UIDocument子类也几乎是空白的:

class Document: UIDocument {    

    let fileExtension = "myFile"

    override init(fileURL url: URL) {
        super.init(fileURL: url)
    }

    /// Convenience method for `init(fileURL:)`
    convenience init(baseName: String) {
        self.init(fileURL: documentsDirectory.appendingPathComponent(baseName).appendingPathExtension(Document.fileExtension))
    }

    override func contents(forType typeName: String) throws -> Any {
        return NSData()
    }

    override func load(fromContents contents: Any, ofType typeName: String?) throws {

    }

}

我总是写信给Documents文件夹,我的查询例程可以验证我的文件是否已成功创建:

public var documentsDirectory: URL {
    return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!
}

func loadFileURLs(from dirURL: URL) -> [URL]? {
    return try? FileManager().contentsOfDirectory(at: dirURL, includingPropertiesForKeys: nil)
}

到目前为止我发现了什么:

  • 即使我已经设置了UTI,也会出现错误。请参阅thisthis
  • 当我发送" myFile"我可以验证我的UTI是否有效。通过AirDrop到我的设备,它正确触发我的应用程序打开。
  • 该错误仅在iOS 11上显示。相同的代码不会在iOS 10上重现错误,例如在the question above中。
  • 我尝试添加UISupportsDocumentBrowser密钥,虽然我没有使用浏览器,但它没有解决错误。

发生了什么事?这只是一个"噪音" iOS 11上的错误消息?

如果有人有兴趣,请my GitHub code online

2 个答案:

答案 0 :(得分:3)

解决方法是通过将数据保存到磁盘来创建文件,然后像使用现有文件一样打开它。

您的createDoc(_:)方法会喜欢这样:

@IBAction func createDoc(_ sender: Any) {
  let uuid = UUID().uuidString
  let baseName = "myDoc-\(uuid)"
  let url = documentsDirectory
      .appendingPathComponent(baseName)
      .appendingPathExtension(Document.fileExtension)

  do {
    let emptyFileData = Data()
    try emptyFileData.write(to: url)
    let document = Document(fileURL: url)
    document.open() { completed in
      guard completed else { 
        // handle error
        return 
      }
      doc.close(completionHandler: nil)
      self.verifyNumberOfFiles() 
    }
  } catch {
    // handle error
  }
}

答案 1 :(得分:0)

在Xcode 9.3中,可以在info.plist中指定一个新项目:

支持文档浏览器(是)

这样可以访问应用程序的文档目录(例如,设备上的/ var / mobile / Containers / Data / Application / 3C21358B-9E7F-4AA8-85A6-A8B901E028F5 / Documents)。 Apple开发人员文档here