文件提供程序扩展名,importDocumentator::can';在给定URL(iOS 11.4.1)下读取文件

文件提供程序扩展名,importDocumentator::can';在给定URL(iOS 11.4.1)下读取文件,ios,objective-c,fileprovider-extension,Ios,Objective C,Fileprovider Extension,我在将操作粘贴到文件提供程序扩展名中的容器时遇到问题 如果我将复制的图像或文本粘贴到文件应用程序->我的应用程序->任何文件夹中,则无法读取文件URL处的文件(因此无法上载到我的服务器或存储在本地) readErrorMessage和copyErrorMessage都是: 无法打开文件“text.txt”,因为您没有查看该文件的权限。 我做错了什么 谢谢 UPD:从我的容器、iCloud容器复制的任何文件以及从系统剪贴板的文本/图像/其他数据生成的合成文件都会发生这种情况。看起来您正在处理安全范

我在将操作粘贴到文件提供程序扩展名中的容器时遇到问题

如果我将复制的图像或文本粘贴到文件应用程序->我的应用程序->任何文件夹中,则无法读取文件URL处的文件(因此无法上载到我的服务器或存储在本地)

readErrorMessage和copyErrorMessage都是:

无法打开文件“text.txt”,因为您没有查看该文件的权限。

我做错了什么

谢谢


UPD:从我的容器、iCloud容器复制的任何文件以及从系统剪贴板的文本/图像/其他数据生成的合成文件都会发生这种情况。

看起来您正在处理安全范围的URL

任何访问其沙箱外部文档的应用程序必须满足以下要求:

  • 您的应用程序必须使用文件协调执行所有文件读写操作

  • 如果向用户显示文档的内容,则必须使用文件演示器跟踪文档的状态。如果仅显示文件列表,则不需要文件演示器

  • 不要保存通过打开或移动操作访问的任何URL。始终使用文档选择器、元数据查询或URL的安全范围书签打开文档

  • 这些操作返回安全范围的URL。您必须在访问URL之前调用

  • 如果返回YES,请在使用完该文件后调用

  • 如果您使用的是UIDocument子类,它将自动为您使用安全范围的URL。没有必要打电话或打电话。UIDocument还充当文件演示者并自动处理文件协调。出于这些原因,强烈建议对应用程序沙箱之外的所有文件使用UIDocument子类

因此,您需要在复制此url处的文件之前调用。您的代码可能会变为

- (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:&copyError];
  NSString *copyErrorMessage = copyError.localizedDescription;

  // ....
  // Call |stopAccessingSecurityScopedResource| after everything is done.
  [fileURL stopAccessingSecurityScopedResource];
}

看起来您正在处理安全范围的URL

任何访问其沙箱外部文档的应用程序必须满足以下要求:

  • 您的应用程序必须使用文件协调执行所有文件读写操作

  • 如果向用户显示文档的内容,则必须使用文件演示器跟踪文档的状态。如果仅显示文件列表,则不需要文件演示器

  • 不要保存通过打开或移动操作访问的任何URL。始终使用文档选择器、元数据查询或URL的安全范围书签打开文档

  • 这些操作返回安全范围的URL。您必须在访问URL之前调用

  • 如果返回YES,请在使用完该文件后调用

  • 如果您使用的是UIDocument子类,它将自动为您使用安全范围的URL。没有必要打电话或打电话。UIDocument还充当文件演示者并自动处理文件协调。出于这些原因,强烈建议对应用程序沙箱之外的所有文件使用UIDocument子类

因此,您需要在复制此url处的文件之前调用。您的代码可能会变为

- (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:&copyError];
  NSString *copyErrorMessage = copyError.localizedDescription;

  // ....
  // Call |stopAccessingSecurityScopedResource| after everything is done.
  [fileURL stopAccessingSecurityScopedResource];
}

就这样。谢谢。但请将您的代码更改更正为[fileURL start | stop AccessingSecurityScopedResource];就这样。谢谢。但请将您的代码更改更正为[fileURL start | stop AccessingSecurityScopedResource];