sandbox - Mac沙盒: How to distinguish between "Permission Denied" and "Does not Exist" re: Security-Scoped Bookmarks/URLs?

标签 sandbox nsfilemanager

启动时,我的应用程序会检查用户是否已授予访问某个文件夹的权限(或没有)。如果授予访问权限,应用程序将继续,如果没有,应用程序将显示一个 PowerBox NSOpenPanel - 设置为必要的目录 - 来请求许可。

一旦授予权限,我会将其存储为“安全范围书签”,并在将来的 session 中使用它来保留对该目录的访问权限。

该系统归结为在启动时检查目录的状态:

- (BOOL)needsPermissionForPath:(NSString *)path
{
    return ![[NSFileManager defaultManager] isReadableFileAtPath:path];
}

但是,我当前的模式有一个重大失败:如果文件夹不存在,needsPermissionForPath总是返回 YES,但用户永远无法授予权限。

isReadableFileAtPath: 的文档状态:

Return Value
YES if the current process has read privileges for the file at path; 
otherwise NO if the process does not have read privileges or 
the existence of the file could not be determined.

Discussion
If the file at path is inaccessible to your app, perhaps because it does 
not have search privileges for one or more parent directories, 
this method returns NO. 

Note: Attempting to predicate behavior based on the current state 
of the file system or a particular file on the file system is not 
recommended. Doing so can cause odd behavior or race conditions. 
It's far better to attempt an operation (such as loading a file or 
creating a directory), check for errors, and handle those errors gracefully
than it is to try to figure out ahead of time whether the operation will succeed

这似乎表明我应该继续尝试做我想做的事情。

问题是,我不知道可以采取什么测试操作来区分“用户未授予权限”(这保证我再次显示“请授予权限”面板)和“此文件夹不存在”状态(这保证我忽略该目录并继续)。

如何区分?

或者,我应该尝试创建有问题的目录吗?即使在这种情况下,用户仍然必须向包含的目录授予写入权限,因此这会增加一层额外的权限,这似乎是不必要的。

我认为这是一个先有鸡还是先有蛋的问题。 未经许可无法检查文件夹是否存在,文件夹不存在也无法获取权限。


编辑

基于下面的解决方案,这是我的新方法:

- (BOOL)needsPermissionForPath:(NSString *)path
{
    if ( !path ) {
        return NO;
    }

    NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];
    if ( !url ) {
        return NO;
    }

    NSError *error = nil;
    BOOL reachable = [url checkResourceIsReachableAndReturnError:&error];
    if ( !reachable ) {
        //NSLog(@"Could not reach path (may not be an error; if file does not exist this is expected behavior) %@ with: %@", [NSURL fileURLWithPath:path], error);
        return NO;
    }

    return ![[NSFileManager defaultManager] isReadableFileAtPath:path];
}

最佳答案

  • 使用以下代码检查文件 URL 是否存在且可访问。即使 URL 位于沙箱之外,也会返回正确的信息。

     NSError *erroer = nil;
     BOOL reachable = [unarchivedURL checkResourceIsReachableAndReturnError:&erroer];
    
  • 如果可访问但不可读:请求许可

关于sandbox - Mac沙盒: How to distinguish between "Permission Denied" and "Does not Exist" re: Security-Scoped Bookmarks/URLs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23703956/

相关文章:

ios - iPhone 复制文件

iphone - NSFileManager 多实例写入原子性

C++ - 用户空间代码中的二级保护代码

android - 发布 Instant App 时 :Invalid target sandbox version

windows-8 - Windows 8/Windows Server 2012 中基于功能的安全性

cocoa - 包和 NSFileManager enumeratorAtURL :includingPropertiesForKeys:options:errorHandler:

ios - 在 icloud 上禁用文档文件夹及其所有子文件夹的备份?

c# - 沙盒化 ActiveX 组件

.net - Appdomain 是沙箱 IronPython 的唯一方法吗?

iOS:从文档目录获取文件名到 NSMutableArray