No权限查看从IOS文档提供程序传递回的文档在打开操作中

我在iOS 9.2中创建文件/文档提供程序,并已将导入和导出操作正常工作。但是,开放的操作正在给我带来麻烦。

MY Document Provider将示例文件写入其文件提供程序存储,特别是在此位置:

/private/var/mobile/Containers/Shared/AppGroup/41EDED34-B449-4FE0-94BA-4046CC573544/File Provider Storage/test.txt

我已经能够从文档提供商内部读回并验证数据是正确的。但是,当我尝试读取传递给主机应用程序的URL时,我得到权限错误:

Error Domain=NSCocoaErrorDomain Code=257 "The file “test.txt” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/41EDED34-B449-4FE0-94BA-4046CC573544/File Provider Storage/test.txt, NSUnderlyingError=0x15eda7700 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

所以我不确定这将如何工作。如果有人可以澄清我应该在这里做的事情,我会很感激。

文件写入:(在我调用dismansgrantingaccesstourl之前调用文档提供程序:)

NSString *contents = @"this is a dynamically created text file";
NSLog(@"write to file = %@", fileName);
NSError *err;
[contents writeToFile:fileName 
          atomically:NO 
            encoding:NSStringEncodingConversionAllowLossy 
                error:&err];

file读取:(在DocumentPicker中的主机应用程序中调用:didpickdocumentaturl 🙂

NSString *readback = [[NSString alloc] initWithContentsOfFile:[url path]
                                                    usedEncoding:nil
                                                        error:&err];

我始于Apple的示例代码并通过他们的文档阅读,但没有运气解释为什么这失败。

对于我的文件提供程序,仅调用init:函数。我不确定这是正常的,还是应该调用其他方法来打开操作。这是我的init代码:

- (instancetype)init {
    self = [super init];
    if (self) {
        [self.fileCoordinator coordinateWritingItemAtURL:[self documentStorageURL] options:0 error:nil byAccessor:^(NSURL *newURL) {
            // ensure the documentStorageURL actually exists

            NSError *error = nil;
            [[NSFileManager defaultManager] createDirectoryAtURL:newURL withIntermediateDirectories:YES attributes:nil error:&error];
        }];
    }
    return self;
}

我验证了上面的错误是nil,newul如下:

file:///private/var/mobile/Containers/Shared/AppGroup/41EDED34-B449-4FE0-94BA-4046CC573544/File%20Provider%20Storage/

Update:我开始了解为什么主机应用程序无法读取该文件。我认为这是因为我在托管应用程序中没有该应用程序组的权限。但是,由于主机应用程序应该与支持适当扩展的任何文档提供程序一起使用,因此我认为尝试和添加此权限不会有意义。

我猜测了我的文件提供商未被调用的原因(除了它的init之外:)是因为“打开”返回的文件被检测到本地,因此不需要复制。要传递本地文件,文档表示您必须通过DocumentStorageURL中的URL,但是(按定义?)将被映射到主机应用程序无法访问的App组。

So I’m not sure how this will ever work. If someone can clarify what I should be doing here, I’d appreciate it.

回答 2

  1. 赞同 21

    在通过文档中进行更多挖掘,我终于找到了问题:在我尝试访问它之前,我需要在URL上调用“startaccessingsecurityscopedresource”。

    在本文档中“访问沙箱外的文件”部分:

    https://developer.apple.com/library/ios/documentation/filemanagement/conceptual/documentpickerprogramingguide/accessingdocuments/accessingdocuments.html.

    Locksleyu
    谢谢,这就是我要找的东西,但对于fileProvider扩展......导入文档时,您必须在FileURL上调用此主题在iOS 11中的文件应用程序中具有相同问题的人。zeotyn
    我称为方法startaccessingseecurityScopEdSource for返回的URL,此方法返回true,但我仍然无法读取文件的内容,与您的错误相同。纪念日
  2. 赞同 0

    The accepted answer is right, here's just an instant code:

        guard filePath.startAccessingSecurityScopedResource(), 
              let data = try? Data(contentsOf: filePath) else { return }
        filePath.stopAccessingSecurityScopedResource()
        // Do your business
    

    IOS开发人员