Mar*_*ark 5 cocoa mac-app-store appstore-sandbox
我有一个基本的Cocoa应用程序,可以让用户管理文件列表。通过拖放添加文件,并且在应用程序重新启动期间,我将访问权限保留在安全的书签中。
到目前为止,一切都很好。允许该应用读取和写入用户的文件,但是重命名失败并出现权限错误,声称不允许我的应用访问父文件夹。
码:
[[NSFileManager defaultManager] moveItemAtPath:currentPath
toPath:newPath error:&error]
Run Code Online (Sandbox Code Playgroud)
错误:
Error Domain=NSCocoaErrorDomain Code=513 "“Some image.jpg” couldn’t
be moved because you don’t have permission to access “some folder”
Run Code Online (Sandbox Code Playgroud)
我发誓这只在昨天才起作用,但没有任何变化。我假设如果用户允许通过“打开”对话框访问文件或拖放文件,则应允许沙盒应用程序重命名文件。
您面临的问题不在于坚持任何东西,而在于沙箱的工作方式:
规则是……
要重命名文件(实际上是执行移动操作),
您需要对该文件的父目录具有写入权限。
我们的问题是……
如果您拖动文件,沙箱只会扩展对这些文件的访问权限,而不是它们的父目录,因此此错误表明它需要权限
现在,尝试拖动包含这些文件的文件夹,您会发现一切正常:)
那么我们该怎么办 ?
一个简单的解决方案是要求用户通过 NSOpenPanel 选择一个“工作”目录,这样沙箱就可以访问,而不会在用户每次希望重命名时疏远他
但是我们现在正在打扰用户他甚至不应该知道的废话大约在第一位!
所以对我来说这是糟糕的设计/用户体验
现在我已经阅读了关于沙箱的文档,我注意到NSFileCoordinator有一个名为itemAtURL:willMoveToURL的方法:
Wich 把我带到了这个小片段 (我在这里重写是因为它缺少 willMove 函数)
我们想要在这里做的是为了重命名而请求一个沙箱扩展:
NSURL *sourceURL = document.fileURL;
NSURL *destinationURL = [[sourceURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:fileName isDirectory:NO];
NSError *writeError = nil;
__block NSError *moveError = nil;
__block BOOL success = NO;
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[coordinator coordinateWritingItemAtURL:sourceURL
options:NSFileCoordinatorWritingForMoving
writingItemAtURL:destinationURL
options:NSFileCoordinatorWritingForReplacing
error:&writeError
byAccessor:^(NSURL *newURL1, NSURL *newURL2)
{
NSFileManager *fileManager = [NSFileManager new];
[coordinator itemAtURL:sourceURL willMoveToURL:destinationURL];
success = [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:&moveError];
if (success)
{
[coordinator itemAtURL:newURL1 didMoveToURL:newURL2];
}
}];
Run Code Online (Sandbox Code Playgroud)
可悲的是,此方法似乎仅针对更改文件扩展名而不是重命名,因此日志中出现此错误:
NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 1
Run Code Online (Sandbox Code Playgroud)
耶,苹果,耶