我在File Provider扩展程序中无法将粘贴操作粘贴到我的容器中。
如果我将复制的图像或文本粘贴到“文件”应用程序->“我的应用程序”->任何文件夹中,则无法读取fileURL上的文件(结果是无法将其上传到我的服务器或本地存储)。
- (void)importDocumentAtURL:(NSURL *)fileURL
toParentItemIdentifier:(NSFileProviderItemIdentifier)parentItemIdentifier
completionHandler:(void (^)(NSFileProviderItem _Nullable importedDocumentItem, NSError * _Nullable error))completionHandler
{
NSError *readError = nil;
NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:NSDataReadingMappedAlways error:&readError];
NSString *readErrorMessage = readError.localizedDescription;
NSURL *myFileURL = [NSFileProviderManager.defaultManager.documentStorageURL URLByAppendingPathComponent:@"temp.dat"];
NSError *copyError = nil;
BOOL copyResult = [_fileManager copyItemAtURL:fileURL toURL:myFileURL error:©Error];
NSString *copyErrorMessage = copyError.localizedDescription;
...
readErrorMessage和copyErrorMessage都是:
由于您没有查看权限,因此无法打开文件“ text.txt”。
我在这里做什么错了?
谢谢。
UPD::从我的容器,iCloud容器复制的任何文件,以及从系统剪贴板的文本/图像/其他数据生成的合成文件都将发生这种情况。
答案 0 :(得分:1)
好像您正在使用安全范围内的URL。
根据Document Picker Programming Guide
任何访问其沙箱外部文档的应用都必须满足以下要求:
您的应用必须使用文件协调功能执行所有文件读取和写入操作。
如果向用户显示文档的内容,则必须使用文件演示器跟踪文档的状态。如果您仅显示文件列表,则不需要文件演示者。
请勿保存通过打开或移动操作访问的任何URL。始终使用文档选择器,元数据查询或URL的安全范围书签来打开文档。
- 这些操作返回安全范围内的URL。您必须先致电startAccessingSecurityScopedResource才能访问URL。
- 如果startAccessingSecurityScopedResource返回是,请在使用完文件后调用stopAccessingSecurityScopedResource。
- 如果您使用的是UIDocument子类,它将自动为您使用安全范围的URL。无需致电startAccessingSecurityScopedResource或stopAccessingSecurityScopedResource。 UIDocument还充当文件演示者,并自动处理文件协调。由于这些原因,强烈建议对应用程序沙箱之外的所有文件使用UIDocument子类。
因此,您需要在复制此URL上的文件之前调用startAccessingSecurityScopedResource。您的代码可能会变成
。- (void)importDocumentAtURL:(NSURL *)fileURL
toParentItemIdentifier:(NSFileProviderItemIdentifier)parentItemIdentifier
completionHandler:(void (^)(NSFileProviderItem _Nullable importedDocumentItem, NSError * _Nullable error))completionHandler
{
NSError *readError = nil;
NSData *fileData = [NSData dataWithContentsOfURL:fileURL options:NSDataReadingMappedAlways error:&readError];
NSString *readErrorMessage = readError.localizedDescription;
NSURL *myFileURL = [NSFileProviderManager.defaultManager.documentStorageURL URLByAppendingPathComponent:@"temp.dat"];
// Call |startAccessingSecurityScopedResource| before working on the url
[fileURL startAccessingSecurityScopedResource];
NSError *copyError = nil;
BOOL copyResult = [_fileManager copyItemAtURL:fileURL toURL:myFileURL error:©Error];
NSString *copyErrorMessage = copyError.localizedDescription;
// ....
// Call |stopAccessingSecurityScopedResource| after everything is done.
[fileURL stopAccessingSecurityScopedResource];
}