在沙盒应用中访问桌面

7

我正在开发一个应用程序,其中有一个功能是打开新拍摄的屏幕截图。我希望通过Mac App Store分发它。不幸的是,它需要进行沙盒处理。

为了找到新的屏幕截图,我运行了NSMetaDataQuery。它返回了一些条目,但不幸的是,我无法获取它们的URL,因为它们在桌面上(超出了我的应用程序的沙盒范围)。

我该怎么办?

这是一些代码:

query = [[NSMetadataQuery alloc] init];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidStartGatheringNotification object:query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidUpdateNotification object:query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidFinishGatheringNotification object:query];

[query setDelegate:self];
[query setPredicate:[NSPredicate predicateWithFormat:@"kMDItemIsScreenCapture = 1"]];
[query startQuery];

numberOfScreenshots = [query resultCount];
[self uploadToAmazonS3:[[[query results]objectAtIndex:([query resultCount]-1)]valueForAttribute:NSMetadataItemURLKey]];

谢谢

2个回答

14

未经用户许可,您只能访问音乐、电影、图片和下载文件夹。 Entitlements

要获取桌面文件夹的访问权限,您需要向用户请求授权。然后使用名为安全范围书签的机制,了解更多信息请参阅AppSandboxDesignGuide

  1. 使用NSOpenPanel选择文件夹。
  2. 保存书签以备将来使用,例如在NSUserDefaults中。
  3. 获得访问权限。

步骤1和2

    NSOpenPanel *openPanel = [[NSOpenPanel alloc] init];
    [openPanel setCanChooseFiles:NO];
    [openPanel setCanChooseDirectories:YES];
    [openPanel setCanCreateDirectories:YES];

    [openPanel beginWithCompletionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            for (NSURL *fileURL in [openPanel URLs]) {
                NSString *filename = [fileURL path];
                [[NSUserDefaults standardUserDefaults] setObject:filename forKey:@"PathToFolder"];

                NSError *error = nil;
                NSData *bookmark = [fileURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
                     includingResourceValuesForKeys:nil
                                      relativeToURL:nil
                                              error:&error];
                if (error) {
                    NSLog(@"Error creating bookmark for URL (%@): %@", fileURL, error);
                    [NSApp presentError:error];
                } else {
                    [[NSUserDefaults standardUserDefaults] setObject:bookmark forKey:@"PathToFolder"];
                    [[NSUserDefaults standardUserDefaults] synchronize];
                }
                break;
            }
        }        
}];

3.

    NSError *error = nil;
    NSData *bookmark = [[NSUserDefaults standardUserDefaults] objectForKey:@"PathToFolder"];
    bookmarkedURL = [NSURL URLByResolvingBookmarkData:bookmark options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:nil error:&error];
    BOOL ok = [bookmarkedURL startAccessingSecurityScopedResource];
    NSLog(@"Accessed ok: %d %@", ok, [bookmarkedURL relativePath]);

所以,那就是它了。


5

在允许访问后,您还需要获取真实主文件夹的路径 - 即使已启用对真实主文件夹的访问权限,所有其他文件API也仅提供对沙盒文件夹的路径。为了解决这个烦人的问题,苹果建议采用以下方法获取真实主文件夹:

#include <sys/types.h>
#include <pwd.h>

const char *home = getpwuid(getuid())->pw_dir;
NSString *path = [[NSFileManager defaultManager] 
                  stringWithFileSystemRepresentation:home
                  length:strlen(home)];
NSString *realHomeDirectory = [[NSURL fileURLWithPath:path isDirectory:YES] path];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接