在沙盒应用程序中使用 NSSavePanel 替换文件

Posted

技术标签:

【中文标题】在沙盒应用程序中使用 NSSavePanel 替换文件【英文标题】:Replace a file using the NSSavePanel in a sandboxed application 【发布时间】:2011-07-30 17:50:01 【问题描述】:

我使用此代码创建了一个NSSavePanel

NSSavePanel *savePanel = [NSSavePanel savePanel];
savePanel.delegate = self;

savePanel.directoryURL = ...;
savePanel.nameFieldStringValue = ...;

[savePanel beginSheetModalForWindow:self.window
                  completionHandler:^(NSInteger returnCode) 

if (returnCode == NSFileHandlingPanelOKButton) 

// the completion handler


];

如果用户在保存面板中选择了一个已经存在的文件,则会出现警告框““XXX”已经存在。您要替换它吗?”。

如果用户按下“替换”按钮,则在完成处理程序中使用NSFileManagerremoveItemAtPath:error: 方法删除旧文件,然后创建新文件(实际上:它是在临时位置,然后使用moveItemAtPath:toPath:error: 方法移动,但我认为这只是一个实现细节):

if (returnCode == NSFileHandlingPanelOKButton) 
  // overwrite the url, because if we are here is because the user has already
  // expressed its willingness to overwrite the previous file
  NSError *error = nil;
  BOOL res = [[NSFileManager defaultManager] removeItemAtURL:savePanel.URL error:&error];

  if (res) 
    res = [[NSFileManager defaultManager] moveItemAtPath:tmpFilePath toPath:savePanel.URL error:&error];
  

  // ...

在过去,一切都一直正常运行。然而,今天,我开始使用具有“读/写访问”权限的 Lion's Sandbox。

使用沙盒,removeItemAtPath:error: 是成功的,但是下面的moveItemAtPath:toPath:error: 返回错误。

这似乎是合理的,因为 Powerbox 赋予我访问(读取和写入)文件的权限。当我删除此文件时,授予我的权利已用尽。

我猜对了吗?

我该如何解决这个问题?

【问题讨论】:

即使使用replaceItemAtURL:withItemAtURL:而不是removeItemAtURL:error: + moveItemAtPath:toPath:error:,我也会收到错误“您没有权限将文件“XXX”保存在“YYY”文件夹中”。有什么我想念的吗?我哪里错了? 【参考方案1】:

问题是,一旦您删除该文件,您对该文件的权利也会消失。您需要做的是覆盖文件,例如使用[[NSFileManager defaultManager] createFileAtPath:contents:attributes:]。 NSFileManager documentation 对此方法声明如下:

如果路径中已经存在一个文件,如果当前进程具有相应的权限,则此方法会覆盖该文件的内容。

使用NSData/NSMutableData 中的方法也可能会有所帮助。

【讨论】:

【参考方案2】:

使用 [NSFileHandle fileHandleForWritingToURL:error:] 后跟 writeData: 调用覆盖现有文件。此方法适用于沙盒应用程序。对于一个新文件,只需使用 NSFileManager 的方法 createFileAtPath:contents:attributes: 创建它(如果内容不适合内存,则将内容设置为 nil),然后使用 NSFileHandle 写入数据。

如果您想使用核心图形覆盖图像,请参阅NSSavePanel, CGImageDestinationFinalize and OS X sandbox

【讨论】:

以上是关于在沙盒应用程序中使用 NSSavePanel 替换文件的主要内容,如果未能解决你的问题,请参考以下文章

在沙盒应用中访问桌面

在沙盒 mac 中执行拖放

在沙盒模式下禁用小部件回退 (Fortumo)

卡在沙盒帐户中

REST 客户端未在沙盒中生成 Webhook 事件

如何在沙盒 macOS 应用程序中为 ImageEvent 类运行 AppleScript?