为什么 FileManager 在未从文件选择器下载 Google 驱动器文件时无法复制文件?
Why FileManager fails to copy a file when is a not downloaded Google Drive file from file picker?
我有一个函数可以从给定的 URL 中复制文件,该文件通过系统文件选择器返回。
因此,一旦 documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])
的文件选择器 returns 我从 URL 列表中获取第一个 URL 并将其传递给我的函数。
复制功能是这样的:
func copyFile(filePath: URL) -> URL? {
let fileName = filePath.lastPathComponent
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier)!
.appendingPathComponent(fileName)
do {
if FileManager.default.fileExists(atPath: newPath.path) {
try FileManager.default.removeItem(at: newPath)
}
let isSecurityScoped = filePath.startAccessingSecurityScopedResource()
try FileManager.default.copyItem(at: filePath, to: newPath)
if isSecurityScoped {
filePath.stopAccessingSecurityScopedResource();
}
return newPath
} catch (let error) {
NSLog("Cannot copy file from \(filePath.path) to \(newPath.path): \(error)")
}
return nil
}
问题是当文件选择器显示时,我从 Google 驱动器中选择一个尚未下载的文件,它失败并显示
Error Domain=NSCocoaErrorDomain Code=260 "The file “MyFile.xlsx” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/98EF89DD-047F-4474-BCA8-670D267BD526/File Provider Storage/36527922/0B8Y8_VXbYeAaUTd5LUQ1N205TDlONTJlNHBiSHFNUmQ2blJT/MyFile.xlsx, NSUnderlyingError=0x283545f80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
在我看来 FileProvider
在 FileManager
尝试复制文件之前没有下载文件,但不确定是否与权限有关或只是缺少一行。
提前致谢
这可能不是答案,更像是一种解决方法。
最后,NSFileProviderExtension
似乎没有被 Google 正确编码(是的,不知道为什么)。但是在使用 URL
返回到 UIDocumentPickerDelegate
之前不像其他人那样下载文件。例如 iCloud 或 Dropbox。
所以我找到的解决方法是将文件选择器的模式更改为 .import
而不是 .open
,这会强制 Google 文件提供程序扩展将文件下载到/temp 文件夹,您可以在其中实际访问它,并在必要时复制它(但可能不会,因为已经可以访问)。
一个可能不在我们法庭上的警告是,Google 在文件下载时再次未能提供任何反馈(这是其他人正确做的事情)并且选择器在下载文件时有点冻结正在下载。
我有一个函数可以从给定的 URL 中复制文件,该文件通过系统文件选择器返回。
因此,一旦 documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL])
的文件选择器 returns 我从 URL 列表中获取第一个 URL 并将其传递给我的函数。
复制功能是这样的:
func copyFile(filePath: URL) -> URL? {
let fileName = filePath.lastPathComponent
let newPath = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier)!
.appendingPathComponent(fileName)
do {
if FileManager.default.fileExists(atPath: newPath.path) {
try FileManager.default.removeItem(at: newPath)
}
let isSecurityScoped = filePath.startAccessingSecurityScopedResource()
try FileManager.default.copyItem(at: filePath, to: newPath)
if isSecurityScoped {
filePath.stopAccessingSecurityScopedResource();
}
return newPath
} catch (let error) {
NSLog("Cannot copy file from \(filePath.path) to \(newPath.path): \(error)")
}
return nil
}
问题是当文件选择器显示时,我从 Google 驱动器中选择一个尚未下载的文件,它失败并显示
Error Domain=NSCocoaErrorDomain Code=260 "The file “MyFile.xlsx” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/98EF89DD-047F-4474-BCA8-670D267BD526/File Provider Storage/36527922/0B8Y8_VXbYeAaUTd5LUQ1N205TDlONTJlNHBiSHFNUmQ2blJT/MyFile.xlsx, NSUnderlyingError=0x283545f80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
在我看来 FileProvider
在 FileManager
尝试复制文件之前没有下载文件,但不确定是否与权限有关或只是缺少一行。
提前致谢
这可能不是答案,更像是一种解决方法。
最后,NSFileProviderExtension
似乎没有被 Google 正确编码(是的,不知道为什么)。但是在使用 URL
返回到 UIDocumentPickerDelegate
之前不像其他人那样下载文件。例如 iCloud 或 Dropbox。
所以我找到的解决方法是将文件选择器的模式更改为 .import
而不是 .open
,这会强制 Google 文件提供程序扩展将文件下载到/temp 文件夹,您可以在其中实际访问它,并在必要时复制它(但可能不会,因为已经可以访问)。
一个可能不在我们法庭上的警告是,Google 在文件下载时再次未能提供任何反馈(这是其他人正确做的事情)并且选择器在下载文件时有点冻结正在下载。