Replace a file using the NSSavePanel in a sandboxed application

眉间皱痕 提交于 2020-01-04 06:11:09

问题


I create a NSSavePanel using this code:

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

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

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

if (returnCode == NSFileHandlingPanelOKButton) {

// the completion handler

}
}];

If in the save panel the user select an already existing file, appears the alert box "“XXX” already exists. Do you want to replace it?".

If the user press the "Replace" button, in the completion handler the old file is removed with the removeItemAtPath:error: method of NSFileManager, and then the new file is created (in reality: it is created in a temporary location and then moved using moveItemAtPath:toPath:error: method, but I think this is just an implementation detail):

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

  // ...
}

In the past, everything has always worked properly. Today, however, I started to use the Lion's Sandbox with the "Read/Write Access" entitlement.

With the sandbox, the removeItemAtPath:error: is successful, but the following moveItemAtPath:toPath:error: returns an error.

It seems reasonable, because Powerbox gives me the rights to access (in reading and writing) a file. When I remove this file, the right granted to me is exhausted.

Is my guess right?

How can I solve this problem?


回答1:


The problem is that once you delete the file, your rights on that file also vanish. What you need to do instead is overwrite the file, for example using [[NSFileManager defaultManager] createFileAtPath:contents:attributes:]. The NSFileManager documentation states the following for this method:

If a file already exists at path, this method overwrites the contents of that file if the current process has the appropriate privileges to do so.

Using methods from NSData/NSMutableData might also be helpful.




回答2:


Use [NSFileHandle fileHandleForWritingToURL:error:] followed by writeData: calls for overwriting an existing file. This method works for me in sandboxed app. For a new file, just create it with NSFileManager's method createFileAtPath:contents:attributes: (with contents set to nil if contents do not fit into memory) and then use NSFileHandle for writing data.

If you want to overwrite an image using core graphics see NSSavePanel, CGImageDestinationFinalize and OS X sandbox



来源:https://stackoverflow.com/questions/6884924/replace-a-file-using-the-nssavepanel-in-a-sandboxed-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!