I'm making a file encryption app, but when I submit it to the App Store, if I don't enable Sandbox, it gets rejected when I upload it with Transporter.app.
So, I added Sandbox to Entitlements.plist
as follows.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
Now I can upload files with Transporter.app without any problems, but now that I have enabled Sandbox, when I try to write files from NSSavePanel
, the file access seems to be denied as shown below. By the way, I can read files from NSOpenPanel
.
var panel = new NSSavePanel();
panel.CanCreateDirectories = true;
panel.ReleasedWhenClosed = true;
panel.BeginSheet(MainViewController.Window, ret =>
{
panel.EndSheet(MainViewController.Window);
if (ret > 0)
{
DirectoryInfo diParent = Directory.GetParent(panel.Url.Path);
string DirPath = diParent.FullName;
string FileName = Path.GetFileNameWithoutExtension(panel.Url.Path);
var publicKeyFilePath = Path.Combine(DirPath, FileName + ".pub");
var privateFilePath = Path.Combine(DirPath, FileName + ".pvt");
var rsa = new RSACryptoServiceProvider(2048);
var publicKey = rsa.ToXmlString(false);
var privateKey = rsa.ToXmlString(true);
var xml = XElement.Parse(publicKey);
xml.Save(publicKeyFilePath); // <- System.UnauthorizedAccessException
//-----------------------------------
xml = XElement.Parse(privateKey);
xml.Save(privateFilePath);
rsa.Clear();
return guidString;
}
});
xml.Save(publicKeyFilePath); // <- System.UnauthorizedAccessException
Of course, if Sandbox is not enabled, the public key file will be saved without any problem.
What could be the problem?
This problem has been solved.
As mentioned in the comments, it seems that the file name specified by the user in NSSavePanel
was not used as it is, and I generated two files with different extensions, which was caught by the Sandbox limitation.
In this case, I was able to save the desired file by displaying NSSavePanel
twice in a row and saving the file with the user-specified file name.
var panel = new NSSavePanel();
panel.CanCreateDirectories = true;
panel.ReleasedWhenClosed = true;
panel.AllowedFileTypes = new[] { "pub" };
panel.BeginSheet(MainViewController.Window, ret =>
{
XElement xml;
var rsa = new RSACryptoServiceProvider(2048);
panel.EndSheet(MainViewController.Window);
if (ret > 0)
{
var publicKey = rsa.ToXmlString(false);
xml = XElement.Parse(publicKey);
xml.Save(panel.Url.Path); // <- Use the file path selected by the user as is
}
panel = new NSSavePanel();
panel.AllowedFileTypes = new[] { "pvt" };
panel.BeginSheet(MainViewController.Window, rt =>
{
panel.EndSheet(MainViewController.Window);
if (rt > 0)
{
var privateKey = rsa.ToXmlString(true);
xml = XElement.Parse(privateKey);
xml.Save(panel.Url.Path); // <- Use the file path selected by the user as is
}
});
rsa.Clear();
});