问题
Since iOS 11 I have encountered the following error every time I am creating a new document using UIDocument
API:
[ERROR] Could not get attribute values for item /var/mobile/Containers/Data/Application/XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX/Documents/myDoc-XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX.myFile (n).
Error: Error Domain=NSFileProviderInternalErrorDomain Code=1
"The reader is not permitted to access the URL."
UserInfo={NSLocalizedDescription=The reader is not permitted to access the URL.}
Unlike similar questions (1, 2, 3) on SO on this, I am not using UIDocumentBrowserViewController
. I am simply creating a UIDocument and call save()
to the Documents
directory myself. The closest question I found uses UIManagedDocument
. However, in my case, the file is still created and written successfully despite the error message.
Here's the gist of my save routine:
@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()
}
}
}
My UIDocument
subclass is also almost blank for simplicity of this question:
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 {
}
}
I'm always writing to Documents
folder, and my lookup routine can verify that my files are successfully created:
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)
}
What I have discovered so far:
- The error appears even when I set up my UTI already. See this and this.
- I can verify that my UTI works when I send a "myFile" to my device over AirDrop and it correctly triggers my app to open.
- The error appears on iOS 11 only. The same code doesn't reproduce the error on iOS 10, like in the question above.
- I tried adding
UISupportsDocumentBrowser
key although I'm not using the browser but it's not dissolve the error.
What is happening? Is this just a "noise" error message on iOS 11?
Here's 🔨 my GitHub code online if anyone is interested.
回答1:
A workaround for this is to create the file by saving its data to the disk, and then open it as you would with an existing file.
Your createDoc(_:)
method would then like this:
@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
}
}
回答2:
In Xcode 9.3 it is possible to specify a new item in info.plist:
Supports Document Browser (YES)
This enables access to the application's documents directory (for example, /var/mobile/Containers/Data/Application/3C21358B-9E7F-4AA8-85A6-A8B901E028F5/Documents on a device). Apple Developer doc here.
来源:https://stackoverflow.com/questions/48049671/uidocument-creation-on-ios-11-reader-is-not-permitted-to-access-the-url