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



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

[错误] 无法获取项目/var/mobile/Containers/Data/Application/XXXXXXXXX-XXXX-XXXX-XXXXX-XXXXXXXXX-documents/myDoc-XXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

错误:Error Domain=NSFileProviderInternalErrorDomain Code=1
"不允许读取器访问 URL。">
UserInfo={NSLocalizedDescription=不允许读取器访问 URL。

与关于SO的类似问题(1,2,3)不同,我没有使用UIDocumentBrowserViewController。我只是创建一个UIDocument,并自己调用save()Documents目录。我找到的最接近的问题使用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,也会出现错误。看到这个和这个。
  • 当我通过 AirDrop 向我的设备发送"myFile"时,我可以验证我的 UTI 是否正常工作,并且它会正确触发我的应用程序打开。
  • 该错误仅在iOS 11上显示。相同的代码不会在iOS 10上重现错误,如上面的问题所示。
  • 我尝试添加UISupportsDocumentBrowser键,尽管我没有使用浏览器,但它并没有消除错误。

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

🔨 如果有人感兴趣,这是我的在线GitHub代码。

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

然后,您的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
}
}

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

支持文档浏览器(是)

这允许访问应用程序的文档目录(例如,设备上的/var/mobile/Containers/Data/Application/3C21358B-9E7F-4AA8-85A6-A8B901E028F5/Documents )。苹果开发者文档在这里。

最新更新