在沙盒应用中访问桌面
Posted
技术标签:
【中文标题】在沙盒应用中访问桌面【英文标题】:Accessing the desktop in a Sandboxed app 【发布时间】:2012-08-28 05:58:36 【问题描述】:我正在构建一个具有打开新截屏功能的应用程序。我想使用 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]];
谢谢
【问题讨论】:
【参考方案1】:在不征得用户许可的情况下,您只能访问音乐、电影、图片和下载文件夹。
您必须要求用户授予您对桌面文件夹的访问权限。然后使用称为Security-Scoped Bookmarks 的机制,在AppSandboxDesignGuide 中了解更多信息。
-
使用 NSOpenPanel 选择目录。
保存书签以备将来使用,例如在 NSUserDefaults 中。
获取访问权限
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]);
原来如此。
【讨论】:
【参考方案2】:在您允许访问后,您还需要获取真实主文件夹的路径 - 所有其他文件 API 仅提供沙盒文件夹的路径,即使启用了对真实主文件夹的访问也是如此。为了解决这个烦人的问题,Apple 建议这样做来获取真正的主文件夹:
#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];
【讨论】:
以上是关于在沙盒应用中访问桌面的主要内容,如果未能解决你的问题,请参考以下文章