即使允许访问文件,startAccessingSecurityScopedResource()也返回false

时间:2018-02-02 09:40:57

标签: ios objective-c ios-extensions

我有一个iOS应用程序,它有一个动作扩展名来保存文档。

即使我能够访问该文件,方法startAccessingSecurityScopedResource()在某些情况下也会返回false。

BOOL success = [originalURL startAccessingSecurityScopedResource];    
if (success) {
    NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
    NSError *error = nil;
    [fileCoordinator coordinateReadingItemAtURL:originalURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) { 
        //My Code
    }
}

在上面的代码中,观察到以下内容

从Apple的照片应用程序共享文件时

originalURL = file:///var/mobile/Media/PhotoData/OutgoingTemp/49152B46-E719-41A5-A5D5-21EAE6254246/RenderedPhoto/IMG_0026.JPG 

从MS Word App共享文件时

originalURL = file:///private/var/mobile/Containers/Data/Application/1B0C962F-E7B4-46ED-A9DA-A8213E05A470/tmp/ShareAttachments/%7BC699DC26-37F9-A949-8F69-1F9D6981C4B0%7D/Document.docx

从Apple的Pages App共享文件时

originalURL = file:///private/var/mobile/Containers/Data/Application/CDBBDC79-02C7-4ABF-A6B9-F38B6540E2B1/Documents/Document%20(1).pages

第一种情况(照片应用)中的标记successtrue,而另外两种情况下为false(Word& Pages应用)。

如果我删除了成功标志检查,我可以使用NSFileCoordinator访问所有这三个文件,并且能够将文件复制到我的应用程序中。

因此,我不确定为什么方法startAccessingSecurityScopedResource()在我明显有权复制文件的情况下返回false。

动机是使用动作扩展将从文件编辑器应用程序导出的文件保存到我的iOS应用程序中。

2 个答案:

答案 0 :(得分:1)

我只使用['Cluster 7', '4', '15', '21', '28', '33', '35', '43', '47', '53', '57', '59', '66', '69', '70', '74', '86', '87', '88', '90', '114', '136', '148', '201', '202', '212', '220', '227', '250', '252', '253', '259', '262', '267', '270', '282', '296', '318', '319', '323', '326', '341', 'Cluster 8', '9', '10', '11', '20', '39', '55', '79', '101', '108', '143', '149', '221', '279', '284', '285', '286', '287', '327', '333', '334', '335', '336', 'Cluster 9', '3', '64', '83', '93', '150', '153', '264', '269', '320', '321', '322', 'Cluster 10', '94', '123', '147'] 来确定我需要在success完成处理程序内调用stopAccessingSecurityScopedResource()

NSFileCoordinator

请注意,根据Apple的文档,如果您不打电话给BOOL success = [originalURL startAccessingSecurityScopedResource]; NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; NSError *error = nil; [fileCoordinator coordinateReadingItemAtURL:originalURL options:NSFileCoordinatorReadingForUploading error:&error byAccessor:^(NSURL *newURL) { //My Code if (success) { [originalURL stopAccessingSecurityScopedResource]; } }

  

如果您在不再需要文件系统资源时无法放弃对文件系统资源的访问权限,则您的应用程序会泄漏内核资源。如果泄漏了足够的内核资源,您的应用程序将无法将文件系统位置添加到其沙箱中,例如通过Powerbox或安全范围的书签,直到重新启动。

答案 1 :(得分:0)

如果您要访问的文件是外部文档,并且不在应用程序的沙箱中,那么您将需要startAccessingSecurityScopedResource()访问该文件,并且它将返回true。

如果您访问的文档是应用程序的资产或没有授权,则该方法将返回false。

请参阅此Apple Doc of UIDocumentPickerViewController。它使用NSFileCoordinator读取和写入外部文档。