Mac Sandbox:如何区分" Permission Denied"并且"不存在" re:安全范围的书签/ URL?

时间:2014-05-16 20:22:02

标签: sandbox nsfilemanager

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

授予权限后,我将其存储为“Security-Scoped Bookmark”,并在将来的会话中使用该权限以保留对目录的访问权。

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

- (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];
}

1 个答案:

答案 0 :(得分:2)

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

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